Why does my FTP upload fail intermittently? - c#

I have a bit of C# code (part of a scheduled SSIS job) that uploads a file an FTP. The file is already present on the FTP site, so the job is just overwriting it with a newer version.
Most of the time it works great, but every few weeks it will begin to fail. The most recent time this has happened, I found that the initial error is "427 Aborted, file write error". Other times I have received "451, Local error in processing". After the initial failure, every subsequent time the job tries to run it returns "550 File Unavailable". When I open the site using Filezilla after getting this error, I find that my target file is there but empty. If I delete the empty file using Filezilla, the job will begin working again.
I have altered my code to first delete the file in question, then upload the new one in hopes that will serve as a workaround. I have been unable to reproduce this error, so time will tell if the workaround helps.
That said, I would like to figure out the root cause. I've been able to find very little info on the 427 error. Anyone have any idea how to avoid it or an idea for a better workaround?
Note: the FTP server is a proprietary thing, and I don't have much control over it other than username, password, & port.
My code is below (edited for brevity)...
private void CreateFile(FtpWebRequest request, FtpWebResponse response, string ipAddress, Int16 port, string folderName, string username, string password)
{
string filename = "myfile.csv";
request = (FtpWebRequest)FtpWebRequest.Create(string.Format("ftp://{0}:{1}/{2}/{3}", ipAddress, port, folderName, filename));
request.KeepAlive = false;
request.Credentials = new System.Net.NetworkCredential(username, password);
request.Proxy = null;
request.UsePassive = false;
request.Method = WebRequestMethods.Ftp.DeleteFile;
request.GetResponse();
request = (FtpWebRequest)FtpWebRequest.Create(string.Format("ftp://{0}:{1}/{2}/{3}", ipAddress, port, folderName, filename));
request.KeepAlive = false;
request.Credentials = new System.Net.NetworkCredential(username, password);
request.Proxy = null;
request.UsePassive = false;
request.Method = WebRequestMethods.Ftp.UploadFile;
using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
{
DataTable myList = new DataTable();
System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
da.Fill(myList, Dts.Variables["MyList"].Value);
foreach (DataRow row in myList.Rows)
{
sw.WriteLine(row["col1"]);
}
sw.Flush();
}
}

Related

FTPWebRequest: Unable to connect to server

I've written a site in ASP.NET which uses FTPWebRequest to download a text file from an FTP server every 15 seconds. When I run it on my computer, it works just fine. When I upload it to our server, the FTP download fails. No exception, it just returns 0 values.
I thought there might be an issue with the firewall, so I disabled the Windows firewall, and disabled outgoing firewall, same problem. Tried both active and passive FTP. Is it possible I need to change some settings in IIS Manager?
Running IIS 10 on Server 2012 R2, on the same VM with Exchange 2016.
Part of the code:
public static string[] GetTXT()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("FTP address");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UsePassive = false; //tried it with true as well
request.Credentials = new NetworkCredential("user", "pass");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string result = (reader.ReadToEnd());
}
Eventually discovered I was publishing the site in a subfolder.
The root folder probably contained an older version.
Anyway, thanks for the help!
If just a download from the server FTP, I recommend this class WebClient implemented by Microsoft for your method.
It maybe resolves your problem.
public static string[] GetTXT()
{
using (WebClient client = new WebClient())
{
var path = #"C:\local\path\file.txt";
client.Credentials = new NetworkCredential("log", "pass");
client.DownloadFile("ftp://ftp.example.com/remote/path/file.txt", path);
}
if (File.Exists(path))
{
return File.ReadAllLines(path);
}
//return something
}

FtpWebRequest throws System.Net.WebException: The remote server returned an error: (530) Not logged in

I have a windows service that is attempting to create a folder on my FTP server. The service works fine locally with no issues at all. When I try and execute on the server however I get a 530. What's really odd is that I created a little .aspx page that runs the same code and it works. It only fails in my service code.
var ftpLocation = ConfigurationManager.AppSettings["FtpLocation"];
var ftpUserName = ConfigurationManager.AppSettings["FtpUserName"];
var ftpPassword = ConfigurationManager.AppSettings["FtpPassword"];
var request = (FtpWebRequest)WebRequest.Create(ftpLocation);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.EnableSsl = true;
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
try
{
logger.Debug("Calling MakeDirectory for " + ftpPath);
using (var response = (FtpWebResponse)request.GetResponse())
{
if (response.StatusCode != FtpStatusCode.PathnameCreated)
throw new ApplicationException(string.Format("FTP failed with the following response: {0} - {1}",
response.StatusCode, response.StatusDescription));
response.Close();
}
logger.Debug("Calling MakeDirectory for " + ftpPath);
}
I should also note the directory I'm trying to create has a space in it, but again it works 100% correct on my aspx page.
ugh! I looked at the password at least a dozen times. Turns our our deployment server is replacing 3 characters in our password when it deploys

SharePoint 2007 Warmup Script (Alternative to Http Request)

At the moment I am trying to HTTP response request in my Sharepoint WarmUp script, however for this, I will have to use this code
using (System.IO.StreamReader file = new System.IO.StreamReader(filePath))
while ((line = file.ReadLine()) != null)
{
try
{
WebRequest request = WebRequest.Create(line);
request.Proxy = null;
if ((userName == null) || (userName == ""))
{
request.Credentials = CredentialCache.DefaultCredentials;
}
else
{
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(line), "NTLM", new NetworkCredential(userName, password, DomainName));
request.Credentials = myCache;
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream dataStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(dataStream))
{
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
}
Thread.Sleep(2000);
}
I am not suppose to use any User Account to get response, however I can use Default Credentials that only works when am logged in at server, otherwise they wont gonna work i guess.
Is there any other way of doing it, can't use powershell as its MOSS not sharepoint 2010
cheers
You CAN use Powershell for the warm-up script. You can call stsadm command, make HTTP requests and even use the server object model once you do the proper imports.
This post uses powershell to retrieve available sites using stsadm. Once the script retrieves this list, it instantiates a WebClient object and hits each site URL.
If you only want to hit the sites in a list, you can simply use a WebClient object to do this.
Alternatively, if you have a working Search Service within your SSP, you can configure a scheduled crawl. Not only you'll benefit from up to date crawl results but your site will be warm-up natively without the need of an additional job doing it "just for warming up".

Delete remote files?

I have files that I want to delete. Connection can be from file sharing, http, and ftp.
Example of files to delete:
//mytest//delete//filename.bin
ftp://mytest/delete/filename.bin
http://mytest/delete/filename.bin
Here's what I did:
Uri target = new Uri(#"ftp://mytest/delete/filename.bin");
FileInfo fi = new FileInfo(target.AbsoluteUri);
fi.Delete();
The error I get is:
The given paths format is not supported
Is there a single code that can delete in all these file types?
I have created a simple code for this task(based on thread response).
This is the input:
Uri target = new Uri(#"ftp://tabletijam/FileServer/upload.bin");
Uri target = new Uri(#"http://tabletijam/FileServer/upload.bin");
Uri target = new Uri(#"\\tabletijam\FileServer\upload.bin");
This is the code:
bool DeleteFileOnServer(Uri serverUri)
{
if (serverUri.Scheme == Uri.UriSchemeFtp)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
lblStatus.Content = response.StatusDescription;
response.Close();
return true;
}
else if (serverUri.Scheme == Uri.UriSchemeFile)
{
System.IO.File.Delete(serverUri.LocalPath);
return true;
}
else if (serverUri.Scheme == Uri.UriSchemeHttp || serverUri.Scheme == Uri.UriSchemeHttps)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Http.DeleteFile;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
lblStatus.Content = response.StatusDescription;
response.Close();
return true;
}
else
{
lblStatus.Content = "Unknown uri scheme.";
return false;
}
}
Ftp and File deleted successfully. WebRequestMethods.Http does not contain DeleteFile.
So my question is, how do I delete file from this URI?
http://tabletijam/FileServer/upload.bin
Because FileInfo only works with local files. For each connection you will need a special implementation.
For FTP: (example from MSDN)
public static bool DeleteFileOnServer(Uri serverUri)
{
// The serverUri parameter should use the ftp:// scheme.
// It contains the name of the server file that is to be deleted.
// Example: ftp://contoso.com/someFile.txt.
//
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return false;
}
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse response = (FtpWebResponse) request.GetResponse();
Console.WriteLine("Delete status: {0}",response.StatusDescription);
response.Close();
return true;
}
Using the \\server... notation, you can delete file (that you have access) to on remote servers.
Using FTP, you should the FtpWebRequest.
For HTTP, you could issue a DELETE request, using HttpWebRequest.
For both FTP and HTTP, you might need to supply a username and password. Also normally HTTP servers are not configured to delete files when receiving a DELETE request by default.
For a whole lot of reasons, no, there is not a single unified way you can delete files via each of these protocols.
You could abstract this away into some implementation of your own, however, using an implementation specific to each of the protocols you want to support...
how do i delete file from this uri?
request.Method = "DELETE";
Also, there's a different header supported by WebDAV for controlling the delete...
No, this is not possible. FTP and HTTP are protocols that you are required to stick to. Even though you may be able to delete files when viewing FTP folders in the Explorer doesn't mean it works from C#, too, because the Explorer uses an integrated FTP client. Deleting files via HTTP like that isn't possible at all.

Help needed on Uploading Files in windows mobile

I have an desktop application running on my desktop.
I need to send the file path to the CGI script running at server.
CGI script taks the file path and upload the contents from my machine.
I tried to send the file path through httppost method; it is not working - can any one suggest me how to do.. methods I have tried are:
WebClient upload = new WebClient();
NetworkCredential nc = new NetworkCredential("test", "admin");
Uri URL = new Uri("http:\\10.10.21.55\\cgi-bin\\file_upload.cgi");
upload.Credentials = nc;
byte [] data = upload.UploadFile(filepath, "c:/Data.txt");
Console.WriteLine(data.ToString());
and the other way I tried is:
byte[] buf = new byte[8192];
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("http://10.10.21.55/cgi-bin/file_upload.cgi");
WebResponse rsp = null;
request.Method = "POST";
request.ContentType = "text/xml";
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.WriteLine("hi hiw are you");
writer.Close();
both ways are not working.
but the below answered code works in desktop in winmo its telling WebClient not implimented...
please tell how to send data to script present in server in windows mobile
Is this as simple as getting the WebClient parameters right? (you seem to be passing in file-path as the url, and not using the encoding):
using(WebClient upload = new WebClient()) {
NetworkCredential nc = new NetworkCredential("test", "admin");
upload.Credentials = nc;
byte[] data = upload.UploadFile(
#"http://10.10.21.55/cgi-bin/file_upload.cgi", #"c:\Data.txt");
Console.WriteLine(upload.Encoding.GetString(data));
}

Categories