FtpWebRequest - Issue with the MSDN example - c#

I'm trying to understand the MSDN documentation for FtpWebRequest and more specificaly, how to upload using FTP and C#
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
}
}
}
In the code above they reference 2 file types. Am I right in assuming that testfile.txt is the 'source' file (on the local computer) and test.htm is what testfile.txt will be renamed too?

Yes - you're uploading to test.htm, loading the data from testfile.txt. You can tell that because test.htm is part of the URL (so is remote) whereas testfile.txt is loaded by just creating a StreamReader over a file.
(It's worth noting that this code is pretty bad in various ways, by the way - particularly around resource disposal. Don't treat it as embodying best practices...)

Related

FTP WebException-URI for this command invalid

I have a very simple piece of code.
Everything is correctly written, no typos, and i chattet with a coworker but both of us have simply no idead where the error lies in here.
It smoothly goes through undtil the GetRequestStream() where the exception pops up. It finds the files, encodes it correctly but then can't seem to connect with the server.
This is the code:
public class WebRequestUploadExample
{
public void WebRequestUpload()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(#"ftp://xxxxx");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("xxxxx", "xxxxx");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader(#"D:\ftpTest\Test\Test.txt");
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
}
May be your target server does not support 'passive' mode. Have you tried active-mode? request.UsePassive = false;
FtpWebRequest.UsePassive

c# Upload to ftp with not created directorys on ftp server

This is the path I am trying to upload to the ftp server:
_ftp://ftp-server/products/productxx/versionxx/releasexx/delivery/data.zip
The problem is that the folders "productxx/versionxx/releasexx/delivery/" do not exist on the server.
Can I create them automatically while uploading the .zip file in c#
My coding at the moment is:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create(pathToFtp);
// Method set to UploadFile
request.Method = WebRequestMethods.Ftp.UploadFile;
// set password and username
request.Credentials = new NetworkCredential(UserName, Password);
// write MemoryStream in ftpStream
using (Stream ftpStream = request.GetRequestStream())
{
memoryStream.CopyTo(ftpStream);
}
I am getting the System.Net.WebException: "Can't connect to FTP: (553) File name not allowed" at "using (Stream ftpStream =request.GetRequestStream())"
but if my pathToFtp is _ftp://ftp-server/products/data.zip it´s working well
One of the request methods available is WebRequestMethods.Ftp.MakeDirectory. You should be able to use that to do what you want.
Something like this (though I've not tested it), should do the trick:
async Task CreateDirectory(string path)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
using (var response = (FtpWebResponse)(await request.GetResponseAsync()))
{
Console.WriteLine($"Created: {path}");
}
}
It's answered in more detail here How do I create a directory on ftp server using C#?

Get File Names from Web directory - from Services

Could you please let me know how can i fetch the file names from a web directory at a service level. I have a wrapper services. Inside it I am trying to fetch file names. I couldn't find a solution.
If I understand the question correctly, which I may not since you werent too specific, sounds as easy as getting FTP listing:
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
}
}
}

How can I get file from FTP (using C#)?

Now I know how to copy files from one directory to another, this is really simple.
But now I need to do the same with files from FTP server. Can you give me some example how to get file from FTP while changing its name?
Take a look at How to: Download Files with FTP or downloading all files in directory ftp and c#
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
reader.Dispose();
response.Close();
Edit
If you want to rename file on FTP Server take a look at this Stackoverflow question
Easiest way
The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile.
It takes an URL to the source remote file and a path to the target local file. So you can use a different name for the local file, if you need that.
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
Advanced options
If you need greater control, that WebClient does not offer (like TLS/SSL encryption, ASCII mode, active mode, etc), use FtpWebRequest. Easy way is to just copy an FTP response stream to FileStream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
ftpStream.CopyTo(fileStream);
}
Progress monitoring
If you need to monitor a download progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
byte[] buffer = new byte[10240];
int read;
while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, read);
Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
FtpWebRequest FTP download with ProgressBar
Downloading folder
If you want to download all files from a remote folder, see
C# Download all files and subdirectories through FTP.

How to create a file(.aspx,html,txt) in memory?

I want to create a file with a .aspx extension(or any other extension) completely in memory. Can this be done?
Right now I have a memory stream that has all the stuff I want to write to this file but I don't actually want to create a physical file on the server since then I probably have to enable write permissions for my server. What I want to do is create the file in memory and upload via ftpWebRequest.
Edit.
I must be doing something wrong because I get weird stuff in my file so weird I can't even paste it into my posts.
Basically it is a bunch of squares between everything. Like it almost seems like it fills it in for the spaces. Like If I look closely I will see the tag still but it will have a square between each letter.
Here is a portion of my code. Maybe I am using the wrong encoding?
using (MemoryStream memory = new MemoryStream())
{
UnicodeEncoding uniEncoding = new UnicodeEncoding();
// readByline is the first bunch of data I want for my new file.
memory.Write(uniEncoding.GetBytes(readByLine), 0, readByLine.Length);
// second bunch of data I want for my new file.
memory.Write(uniEncoding.GetBytes(html), 0, html.Length);
// the follow code just figure out the end of the file that I am
// trying to extract some information out of.
string readToEnd = reader.ReadToEnd();
int endIndex = readToEnd.IndexOf(END_FLAG);
endIndex += END_FLAG.Length;
string restOfFile = readToEnd.Substring(endIndex);
// once found I write it the memory stream.
memory.Write(uniEncoding.GetBytes(restOfFile),0,restOfFile.Length);
// now I want to upload my file. I have the same file name already
// existing on the server? Do I have to tell it override it?
FtpWebRequest request2 = (FtpWebRequest)WebRequest.Create(path);
request2.Method = WebRequestMethods.Ftp.UploadFile;
request2.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
// now I am trying your code.
byte[] fileContents = memory.ToArray();
using (Stream writer = request2.GetRequestStream())
{
writer.Write(fileContents, 0, fileContents.Length);
}
FtpWebResponse test = (FtpWebResponse)request2.GetResponse();
return Content("test");
}
You can convert the MemoryStream to a byte[] and then use WebClient.UploadData to upload the file with FTP to some server without writing it on the client to disk first:
webClient.UploadData(
"ftp://remoteserver/remotepath/file.aspx"
memoryStream.ToArray());
FtpWebRequest works as well, of course, but needs a few more lines of code:
FtpWebRequest ftpRequest;
FtpWebResponse ftpResponse;
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://..."));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Proxy = null;
ftpRequest.UseBinary = true;
ftpRequest.Credentials = new NetworkCredential("UserName", "Password");
using (Stream stream = ftpRequest.GetRequestStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.WriteLine("<html><head><title>Hello World</title></head>...");
}
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Well, such a file is really just plain text, with certain formatting - HTML 4.0, XHTML or such.
So yes, you can create that in memory - inside e.g. a StringBuilder, and then save it back out to disk using a StreamWriter or some other means.
If you can't or don't want to write it out to disk, you can of course also put it into a MemoryStream, and interfaces that can read from any arbitrary stream can read from the memory stream, too.
Check out the MSDN docs on FtpWebRequest and on GetRequestStream() method. It has a sample on how to upload from a stream to FTP directly:
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.UploadFile;
// this could be your MemoryStream, of course, that you're reading from
StreamReader sourceStream = new StreamReader(fileName);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
// check the response, do whatever you need to do with it
response.Close();

Categories

Resources