Download Latest File in a SharePoint Folder - c#

My current code downloads a SharePoint file from an absolute URL of the file and writes to local.
I want to change it to use the folder URL instead and downloads file in the folder base on some filter.
Can it be done?
Below is my current code snippet:
string fullFilePath = DownloadSPFile("http://MySharePointSite.com/sites/Collection1/Folder1/File1.docx/");
public static string DownloadSPFile(string urlPath)
{
string serverTempdocPath = "";
try
{
var request = (HttpWebRequest)WebRequest.Create(urlPath);
var credentials = new NetworkCredential("username", "password", "domain");
request.Credentials = credentials;
request.Timeout = 20000;
request.AllowWriteStreamBuffering = false;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
serverTempdocPath = Path.Combine(AppConfig.EmailSaveFilePath + "_DOWNLOADED.eml");
using (FileStream fs = new FileStream(serverTempdocPath, FileMode.Create))
{
byte[] read = new byte[256];
int count = stream.Read(read, 0, read.Length);
while (count > 0)
{
fs.Write(read, 0, count);
count = stream.Read(read, 0, read.Length);
}
}
}
}
}
catch (Exception ex)
{
AppLogger.LogError(ex, "");
throw ex;
}
return serverTempDocPath;
}

If your sharepoint site enables sharepoint rest api, you can get the details very easy.
Get list of files
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files
method: GET
headers:
Authorization: "Bearer " + accessToken
accept: "application/json;odata=verbose" or "application/atom+xml"
and pass query for that
"?filter=$top=1&$orderby=Created desc"
More information

Has you try to format your urlPath ?
like:
string urlPath = "path/to/folder/";
string fileFilter = "Cat.png";
string finalPath= String.format("{0}{1}", urlPath, fileFilter);
(Or anything like this)
(Hope I understand your question and I was able to help you ^^)

Related

PutAsync without altering content of CSV file

I am trying to use HttpClient with putasync to send file to server. The function looks like:
public async Task SendCsvFile(string path,string apiKey)
{
try
{
string clientKey = "";
LoggerService.Logger.CreateLog("Log");
LoggerService.Logger.Info("Start:SendCsvFile");
FileStream fileStream = null;
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient httpClient = new HttpClient(clientHandler);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Add("x-api-key", clientKey);
string url = "https://test.csv";
var content = new MultipartFormDataContent();
var fileName = Path.GetFileName(path);
fileStream = File.OpenRead(path);
StreamContent streamContent = new StreamContent(fileStream);
content.Add(new StreamContent(fileStream), fileName, fileName);
var response = await httpClient.PutAsync(url, content);
if (response.IsSuccessStatusCode == true)
{
LoggerService.Logger.Info("File sent correctly.");
}
else
{
LoggerService.Logger.Error("Error during sending." + response.StatusCode + ";" + response.ReasonPhrase + ";");
}
fileStream.Close();
LoggerService.Logger.Info("End:SendCsvFile");
}
catch (Exception ex)
{
LoggerService.Logger.Error(ex.ToString());
//return 0;
}
//return 1;
}
File is send fine and it works however Content-disposition header is added to the file to the first line, and client doesn't want that. It's the first time I am doing anything with services and I read through a lot but still I don't know what can i change to not alter the content of csv file.
EDIT.
After I send the file header is added to the content so the file looks like that.
Screenshot from client server
All the data is fine, though the client server processes the data in a way that it should start from column names. So my question really is what can I can change to omit that first line and is it even possible. Maybe thats something obvious but i' m just a newbie in this stuff.
Changing to MultipartContent and Clearing Headers almost work but left me with boundary still visible in a file. Eventually I changed to RestSharp and adding content this way got rid of the problem.
public async Task SendCsvFile(string path, string apiKey)
{
try
{
string clientKey = "";
string url = "";
LoggerService.Logger.CreateLog("CreationAndDispatchStatesWithPrices");
LoggerService.Logger.Info("Start:SendCsvFile");
FileStream fileStream = null;
var fileName = Path.GetFileName(path);
fileStream = File.OpenRead(path);
var client = new RestClient(url);
// client.Timeout = -1;
var request = new RestRequest();
request.AddHeader("x-api-key", clientKey);
request.AddHeader("Content-Type", "text/csv");
request.AddParameter("text/csv", File.ReadAllBytes(path), ParameterType.RequestBody);
RestResponse response = client.Put(request);
if (response.IsSuccessful == true)
{
LoggerService.Logger.Info("File sent correctly.");
}
else
{
LoggerService.Logger.Error("Error sending file." + response.StatusCode + ";" + response.ErrorMessage + ";");
}
fileStream.Close();
LoggerService.Logger.Info("End:SendCsvFile");
}
catch (Exception ex)
{
LoggerService.Logger.Error(ex.ToString());
//return 0;
}
//return 1;
}

How to download file from API using Post Method

I have an API using POST Method.From this API I can download the file via Postmen tool.But I would like to know how to download file from C# Code.I have tried below code but POST Method is not allowed to download the file.
Code:-
using (var client = new WebClient())
{
client.Headers.Add("X-Cleartax-Auth-Token", ConfigurationManager.AppSettings["auth-token"]);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string url = ConfigurationManager.AppSettings["host"] + ConfigurationManager.AppSettings["taxable_entities"] + "/ewaybill/download?print_type=detailed";
TransId Id = new TransId()
{
id = TblHeader.Rows[0]["id"].ToString()
};
List<string> ids = new List<string>();
ids.Add(TblHeader.Rows[0]["id"].ToString());
string DATA = JsonConvert.SerializeObject(ids, Newtonsoft.Json.Formatting.Indented);
string res = client.UploadString(url, "POST",DATA);
client.DownloadFile(url, ConfigurationManager.AppSettings["InvoicePath"].ToString() + CboGatePassNo.EditValue.ToString().Replace("/", "-") + ".pdf");
}
Postmen Tool:-
URL : https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed
Header :-
Content-Type : application/json
X-Cleartax-Auth-Token :b1f57327-96db-4829-97cf-2f3a59a3a548
Body :-
[
"GLD24449"
]
using (WebClient client = new WebClient())
{
client.Headers.Add("X-Cleartax-Auth-Token", ConfigurationManager.AppSettings["auth-token"]);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string url = ConfigurationManager.AppSettings["host"] + ConfigurationManager.AppSettings["taxable_entities"] + "/ewaybill/download?print_type=detailed";
client.Encoding = Encoding.UTF8;
//var data = "[\"GLD24449\"]";
var data = UTF8Encoding.UTF8.GetBytes(TblHeader.Rows[0]["id"].ToString());
byte[] r = client.UploadData(url, data);
using (var stream = System.IO.File.Create("FilePath"))
{
stream.Write(r,0,r.length);
}
}
Try this. Remember to change the filepath. Since the data you posted is not valid
json. So, I decide to post data this way.
I think it's straight forward, but instead of using WebClient, you can use HttpClient, it's better.
here is the answer HTTP client for downloading -> Download file with WebClient or HttpClient?
comparison between the HTTP client and web client-> Deciding between HttpClient and WebClient
Example Using WebClient
public static void Main(string[] args)
{
string path = #"download.pdf";
// Delete the file if it exists.
if (File.Exists(path))
{
File.Delete(path);
}
var uri = new Uri("https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed");
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Headers.Add("X-Cleartax-Auth-Token", "b1f57327-96db-4829-97cf-2f3a59a3a548");
client.Encoding = Encoding.UTF8;
var data = UTF8Encoding.UTF8.GetBytes("[\"GLD24449\"]");
byte[] r = client.UploadData(uri, data);
using (var stream = System.IO.File.Create(path))
{
stream.Write(r, 0, r.Length);
}
}
Here is the sample code, don't forget to change the path.
public class Program
{
public static async Task Main(string[] args)
{
string path = #"download.pdf";
// Delete the file if it exists.
if (File.Exists(path))
{
File.Delete(path);
}
var uri = new Uri("https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed");
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = new StringContent("[\"GLD24449\"]", Encoding.UTF8, "application/json")
};
request.Headers.Add("X-Cleartax-Auth-Token", "b1f57327-96db-4829-97cf-2f3a59a3a548");
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using (FileStream fs = File.Create(path))
{
await response.Content.CopyToAsync(fs);
}
}
else
{
}
}

Delete File in SharePoint folder using C#

I am using SharePoint ExcelService to manipulate an excel file and then save it to the Shared Documents folder using
ExcelService.SaveWorkbookCopy()
Now I want to delete those files I saved earlier. What is the best way to achieve this using C# in a Asp.Net MVC Application?
I tried it using the REST Service, but I could not really find any tutorials and as the code is now, I get a WebException "The remote server returned an error: (403) Forbidden."
I tried two versions for my REST URL, neither worked.
var fileSavePath = "http://sharepointserver/Collaboration/workrooms/MyWebSiteName/Shared%20Documents/";
var excelRestPath_1 = "http://sharepointserver/Collaboration/workrooms/MyWebSiteName/_api/web/";
var excelRestPath_2 = "http://sharepointserver/_api/web/";
public static bool DeleteExcelFromSharepoint(int id, string excelRestPath)
{
try
{
string filePath = "/Shared%20Documents/" + id + ".xlsm";
string url = excelRestPath + "GetFileByServerRelativeUrl('" + filePath + "')";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "DELETE";
request.Headers.Add(HttpRequestHeader.IfMatch, "*");
request.Headers.Add("X-HTTP-Method", "DELETE");
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new ApplicationException(String.Format("DELETE failed. Received HTTP {0}", response.StatusCode));
}
return true;
}
}
catch (Exception ex)
{
CustomLogger.Error("Error deleting Excel from Sharepoint", ex);
return false;
}
}
Use nuget package Microsoft.SharePointOnline.CSOM:
using (var sp = new ClientContext("webUrl"))
{
sp.Credentials = System.Net.CredentialCache.DefaultCredentials;
sp.Web.GetFileByServerRelativeUrl(filePath).DeleteObject();
sp.ExecuteQuery();
}
that will ensure that file is removed - if you want to make sure the file existed during removal:
using (var sp = new ClientContext("webUrl"))
{
sp.Credentials = System.Net.CredentialCache.DefaultCredentials;
var file = sp.Web.GetFileByServerRelativeUrl(filePath);
sp.Load(file, f => f.Exists);
file.DeleteObject();
sp.ExecuteQuery();
if (!file.Exists)
throw new System.IO.FileNotFoundException();
}
If you are using REST, you can refer to the link
(https://msdn.microsoft.com/en-us/library/office/dn450841.aspx#bk_File)
My example code is:
string resourceUrl = "https://<BaseURL>/sites/<SubSite>/_api/web/GetFileByServerRelativeUrl('/sites/<SubSite>/Documents/New Folder/xyz.docx')";
var wreq = WebRequest.Create(resourceUrl) as HttpWebRequest;
wreq.Headers.Remove("X-FORMS_BASED_AUTH_ACCEPTED");
wreq.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
wreq.Headers.Add("X-HTTP-Method", "DELETE");
//wreq.Headers.Add("Authorization", "Bearer " + AccessToken);
wreq.UseDefaultCredentials = true;
wreq.Method = "POST";
wreq.Accept = "application/json; odata=verbose";
wreq.Timeout = 1000000;
wreq.AllowWriteStreamBuffering = true;
wreq.ContentLength = 0;
string result = string.Empty;
string JsonResult = string.Empty;
try
{
WebResponse wresp = wreq.GetResponse();}
catch (Exception ex)
{
LogError(ex);
result = ex.Message;
}
Having tried the answers above and but still not getting the files deleted I found this and it works perfectly
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(“FullSharePointURIofDocument“);
request.Timeout = System.Threading.Timeout.Infinite;
request.Credentials = new
System.Net.NetworkCredential(“SharePointUser“,”SharePointUserPassword“);
request.Method = “DELETE“;
var response = (System.Net.HttpWebResponse)request.GetResponse();
thanks to BizTalkBox

Create file to Onedrive programmatically from C#?

I want to create a doc, docx, pptx or excel file from C# direct to my Onedrive account.
I have try this but it's not working for me. Anybody have any idea what I did wrong ? Thanks
public async Task<ActionResult> CreateWordFile()
{
LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
if (loginStatus.Status == LiveConnectSessionStatus.Connected)
{
var fileData = new Dictionary<string, object>();
fileData.Add("name", "Document.docx");
fileData.Add("Content-Type", "multipart/form-data; boundary=A300x");
fileData.Add("type", "file");
LiveOperationResult getResult = await connectedClient.PostAsync("me/skydrive/files", fileData);
}
return View();
}
EDITED:
The error that I get is this one:
"The header 'Content-Type' is missing the required parameter: 'boundary'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: Microsoft.Live.LiveConnectException: The header 'Content-Type' is missing the required parameter: 'boundary'."
A couple of things:
The dictionary provided to PostAsync only populates fields in the request body, and so adding Content-Type in there doesn't have any effect
File resources are mean to be created using the UploadAsync method, which requires content. I don't believe there's an API you can call to tell the service to create a blank Office document.
I have something else. I created an HttpWebRequest and I set some parameters. Now it create the file to my onedrive account as a docx but when I try to open the file from my account an error message appear and it's saying something like "Something wrong has happened. We could not open the file". The file exist but it can't be open.
The code that I wrote is this. Any suggestions ?
public async Task<ActionResult> CreateWordFile()
{
string body = "--A300x\r\n"
+ "Content-Disposition: form-data; name=\"file\"; filename=\"csm.docx\"\r\n"
+ "Content-Type: application/octet-stream\r\n"
+ "\r\n"
+ "This is some content\r\n"
+ "\r\n"
+ "--A300x--\r\n";
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(body);
Stream stream = new MemoryStream(fileBytes);
LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
if (loginStatus.Status == LiveConnectSessionStatus.Connected)
{
connectedClient = new LiveConnectClient(this.authClient.Session);
string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=A300x";
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials = System.Net.CredentialCache.DefaultCredentials;
httpWebRequest2.ContentLength = fileBytes.Length;
Stream stream2 = httpWebRequest2.GetRequestStream();
stream2.Write(fileBytes, 0, fileBytes.Length);
WebResponse webResponse2 = httpWebRequest2.GetResponse();
}
return View();
}
Finally I create a docx file from c#. I put here the solution (the code from the method is not refactored so it can be split in a severeal methods).
public async Task<ActionResult> CreateWordFile()
{
LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
if (loginStatus.Status == LiveConnectSessionStatus.Connected)
{
connectedClient = new LiveConnectClient(this.authClient.Session);
string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;
MemoryStream streamDoc = new MemoryStream();
DocX doc = DocX.Create(streamDoc);
string headlineText = "Constitution of the United States";
string paraOne = ""
+ "We the People of the United States, in Order to form a more perfect Union, "
+ "establish Justice, insure domestic Tranquility, provide for the common defence, "
+ "promote the general Welfare, and secure the Blessings of Liberty to ourselves "
+ "and our Posterity, do ordain and establish this Constitution for the United "
+ "States of America.";
// A formatting object for our headline:
var headLineFormat = new Formatting();
headLineFormat.FontFamily = new System.Drawing.FontFamily("Arial Black");
headLineFormat.Size = 18D;
headLineFormat.Position = 12;
// A formatting object for our normal paragraph text:
var paraFormat = new Formatting();
paraFormat.FontFamily = new System.Drawing.FontFamily("Calibri");
paraFormat.Size = 10D;
doc.InsertParagraph(headlineText, false, headLineFormat);
doc.InsertParagraph(paraOne, false, paraFormat);
doc.Save();
var docFile = File(streamDoc, "application/octet-stream", "FileName.docx");
MemoryStream streamFile = new MemoryStream();
docFile.FileStream.Position = 0;
docFile.FileStream.CopyTo(streamFile);
var bites = streamFile.ToArray();
Stream stream2 = new MemoryStream(bites);
try
{
LiveOperationResult getResult = await connectedClient.UploadAsync("me/skydrive", docFile.FileDownloadName, stream2, OverwriteOption.Overwrite);
}
catch(WebException ex)
{
}
}
return View("~/Views/Auth/EditFile.cshtml");
}
I also foud the answer to create an xlsx file.
public async Task<ActionResult> CreateExcelFile()
{
LiveLoginResult loginStatus = await authClient.InitializeWebSessionAsync(HttpContext);
if (loginStatus.Status == LiveConnectSessionStatus.Connected)
{
connectedClient = new LiveConnectClient(this.authClient.Session);
string url = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + this.authClient.Session.AccessToken;
XSSFWorkbook wb = new XSSFWorkbook();
// create sheet
XSSFSheet sh = (XSSFSheet)wb.CreateSheet("Sheet1");
// 10 rows, 10 columns
for (int i = 0; i < 100; i++)
{
var r = sh.CreateRow(i);
for (int j = 0; j < 100; j++)
{
r.CreateCell(j);
}
}
MemoryStream stream = new MemoryStream();
wb.Write(stream);
stream.Dispose();
var arrBites = stream.ToArray();
MemoryStream newStream = new MemoryStream(arrBites);
var docFile = File(newStream, "application/octet-stream", "Excel.xlsx");
MemoryStream streamFile = new MemoryStream();
docFile.FileStream.Position = 0;
docFile.FileStream.CopyTo(streamFile);
var bites = streamFile.ToArray();
Stream stream2 = new MemoryStream(bites);
try
{
LiveOperationResult getResult = await connectedClient.UploadAsync("me/skydrive", docFile.FileDownloadName, stream2, OverwriteOption.Overwrite);
}
catch (WebException ex)
{
}
}
return View();
}

Listing server folders and sub folders using C# FtpWebRequest

I am trying to get full list of files, directories and sub-directories on tree view using StreamReader. The problem is it took too long and throws *"Operation time out exception" and shows only one level.
Here is my code
public void getServerSubfolder(TreeNode tv, string parentNode) {
string ptNode;
List<string> files = new List<string> ();
try {
FtpWebRequest request = (FtpWebRequest) WebRequest.
Create(parentNode);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(this.userName, this.Password);
request.UseBinary = true;
request.UsePassive = true;
request.Timeout = 10000;
request.ReadWriteTimeout = 10000;
request.KeepAlive = false;
FtpWebResponse response = (FtpWebResponse) request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string fileList;
string[] fileName;
//MessageBox.Show(reader.ReadToEnd().ToString());
while (!reader.EndOfStream) {
fileList = reader.ReadLine();
fileName = fileList.Split(' ');
if (fileName[0] == "drwxr-xr-x") {
// if it is directory
TreeNode tnS = new TreeNode(fileName[fileName.Length - 1]);
tv.Nodes.Add(tnS);
ptNode = parentNode + "/" + fileName[fileName.Length - 1] + "/";
getServerSubfolder(tnS, ptNode);
} else files.Add(fileName[fileName.Length - 1]);
}
reader.Close();
response.Close();
} catch (Exception ex) {
MessageBox.Show("Sub--here " + ex.Message + "----" + ex.StackTrace);
}
}
You have to read (and cache) whole listing before recursing into subdirectories, otherwise the top-level request will timeout before you complete subdirectories listing.
You can keep using ReadLine, no need to use ReadToEnd and separate the lines yourself.
void ListFtpDirectory(
string url, string rootPath, NetworkCredential credentials, List<string> list)
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url + rootPath);
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials = credentials;
List<string> lines = new List<string>();
using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader = new StreamReader(listStream))
{
while (!listReader.EndOfStream)
{
lines.Add(listReader.ReadLine());
}
}
foreach (string line in lines)
{
string[] tokens =
line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
string name = tokens[8];
string permissions = tokens[0];
string filePath = rootPath + name;
if (permissions[0] == 'd')
{
ListFtpDirectory(url, filePath + "/", credentials, list);
}
else
{
list.Add(filePath);
}
}
}
Use the function like:
List<string> list = new List<string>();
NetworkCredential credentials = new NetworkCredential("user", "mypassword");
string url = "ftp://ftp.example.com/";
ListFtpDirectory(url, "", credentials, list);
A disadvantage of the above approach is that it has to parse server-specific listing to retrieve information about files and folders. The code above expects a common *nix-style listing. But many servers use a different format.
The FtpWebRequest unfortunately does not support the MLSD command, which is the only portable way to retrieve directory listing with file attributes in FTP protocol.
If you want to avoid troubles with parsing the server-specific directory listing formats, use a 3rd party library that supports the MLSD command and/or parsing various LIST listing formats; and recursive downloads.
For example with WinSCP .NET assembly you can list whole directory with a single call to the Session.EnumerateRemoteFiles:
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "user",
Password = "mypassword",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// List files
IEnumerable<string> list =
session.EnumerateRemoteFiles("/", null, EnumerationOptions.AllDirectories).
Select(fileInfo => fileInfo.FullName);
}
Internally, WinSCP uses the MLSD command, if supported by the server. If not, it uses the LIST command and supports dozens of different listing formats.
(I'm the author of WinSCP)
I'm doing similar things, but instead of using StreamReader.ReadLine() for each one, I get it all at once with StreamReader.ReadToEnd(). You don't need ReadLine() to just get a list of directories. Below is my entire code (Entire howto is explained in this tutorial):
FtpWebRequest request=(FtpWebRequest)FtpWebRequest.Create(path);
request.Method=WebRequestMethods.Ftp.ListDirectoryDetails;
List<ftpinfo> files=new List<ftpinfo>();
//request.Proxy = System.Net.WebProxy.GetDefaultProxy();
//request.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
request.Credentials = new NetworkCredential(_username, _password);
Stream rs=(Stream)request.GetResponse().GetResponseStream();
OnStatusChange("CONNECTED: " + path, 0, 0);
StreamReader sr = new StreamReader(rs);
string strList = sr.ReadToEnd();
string[] lines=null;
if (strList.Contains("\r\n"))
{
lines=strList.Split(new string[] {"\r\n"},StringSplitOptions.None);
}
else if (strList.Contains("\n"))
{
lines=strList.Split(new string[] {"\n"},StringSplitOptions.None);
}
//now decode this string array
if (lines==null || lines.Length == 0)
return null;
foreach(string line in lines)
{
if (line.Length==0)
continue;
//parse line
Match m= GetMatchingRegex(line);
if (m==null) {
//failed
throw new ApplicationException("Unable to parse line: " + line);
}
ftpinfo item=new ftpinfo();
item.filename = m.Groups["name"].Value.Trim('\r');
item.path = path;
item.size = Convert.ToInt64(m.Groups["size"].Value);
item.permission = m.Groups["permission"].Value;
string _dir = m.Groups["dir"].Value;
if(_dir.Length>0 && _dir != "-")
{
item.fileType = directoryEntryTypes.directory;
}
else
{
item.fileType = directoryEntryTypes.file;
}
try
{
item.fileDateTime = DateTime.Parse(m.Groups["timestamp"].Value);
}
catch
{
item.fileDateTime = DateTime.MinValue; //null;
}
files.Add(item);
}
return files;

Categories