I want to upload image by using ftp account. My code is like this. But when I choose image and submit, It says me "Could not find file 'C:\Program Files (x86)\IIS Express\picture.jpg'." I know my image is on my desktop and I choose from there. If I copy my image manually this IIS folder, it will upload but this is not sensible. I must choose my image where I want. But it is looking for in IIS Express folder.
[HttpPost, ValidateInput(false)]
public ActionResult Insert(Press model, HttpPostedFileBase uploadfile)
{
...........
...........
...........
...........
if (uploadfile.ContentLength > 0)
{
string fileName = Path.Combine(uploadfile.FileName);
var fileInf = new FileInfo(fileName);
var reqFtp =
(FtpWebRequest)
FtpWebRequest.Create(
new Uri("ftp://ftp.adres.com" + fileInf.Name));
reqFtp.Credentials = new NetworkCredential(username, password);
reqFtp.KeepAlive = false;
reqFtp.Method = WebRequestMethods.Ftp.UploadFile;
reqFtp.UseBinary = true;
reqFtp.ContentLength = uploadfile.ContentLength;
int bufferlength = 2048;
byte[] buff = new byte[bufferlength];
int contentLen;
FileStream fs = fileInf.OpenRead();
try
{
Stream strm = reqFtp.GetRequestStream();
contentLen = fs.Read(buff, 0, bufferlength);
while (contentLen != 0)
{
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, bufferlength);
}
strm.Close();
fs.Close();
}
catch (Exception ex)
{
}
}
...........
...........
...........
...........
return View();
}
}
I found a solution for my problem and I want to share here, maybe a person can benefit
void UploadToFtp(HttpPostedFileBase uploadfile)
{
var uploadurl = "ftp://ftp.adress.com/";
var uploadfilename = uploadfile.FileName;
var username = "ftpusername";
var password = "ftppassword";
Stream streamObj = uploadfile.InputStream;
byte[] buffer = new byte[uploadfile.ContentLength];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
string ftpurl = String.Format("{0}/{1}", uploadurl, uploadfilename);
var requestObj = FtpWebRequest.Create(ftpurl) as FtpWebRequest;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential(username, password);
Stream requestStream = requestObj.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
requestObj = null;
}
Ensure the value in fileName is what you are expecting here:
string fileName = Path.Combine(uploadfile.FileName);
You most likely need to pass the path as a string, as well as the filename into the Combine method.
string fileName = Path.Combine(varFilePath, uploadfile.FileName);
Path.Combine expects an array of strings to combine: https://msdn.microsoft.com/en-us/library/system.io.path.combine%28v=vs.110%29.aspx
How to upload file by ftp using Asp.net MVC.
View
<form method="post" enctype="multipart/form-data">
<input type="file" id="postedFile" name="postedFile" />
<input type="submit" value="send" />
</form>
Controller ActionResult
[HttpPost]
public ActionResult Index(HttpPostedFileBase postedFile)
{
//FTP Server URL.
string ftp = "ftp://ftp.YourServer.com/";
//FTP Folder name. Leave blank if you want to upload to root folder.
string ftpFolder = "test/";
byte[] fileBytes = null;
string ftpUserName = "YourUserName";
string ftpPassword = "YourPassword";
//Read the FileName and convert it to Byte array.
string fileName = Path.GetFileName(postedFile.FileName);
using (BinaryReader br = new BinaryReader(postedFile.InputStream))
{
fileBytes = br.ReadBytes(postedFile.ContentLength);
}
try
{
//Create FTP Request.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp + ftpFolder + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
//Enter FTP Server credentials.
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.ContentLength = fileBytes.Length;
request.UsePassive = true;
request.UseBinary = true;
request.ServicePoint.ConnectionLimit = fileBytes.Length;
request.EnableSsl = false;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileBytes, 0, fileBytes.Length);
requestStream.Close();
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
catch (WebException ex)
{
throw new Exception((ex.Response as FtpWebResponse).StatusDescription);
}
return View();
}
For upload large files you can add this line to your web.config
Thanks to Karthik Ganesan
<httpRuntime maxRequestLength="whatever value you need in kb max value is 2,147,483,647 kb" relaxedUrlToFileSystemMapping="true" />
under system.web section the default is 4 mb size limit
Related
While executing the below code I am getting the following error
(The underlying connection was closed The server committed a protocol
violation )
. Please help on this. I almost go throw every article about the error still not getting the solution.
Thanks in Advance.
private static void Upload()
{
string sourceFile = System.IO.Path.Combine(filepath, filename);
string ftpServerIP = "Hostname";
string ftpUserID = "UserName";
string ftpPassword = "Password";
FileInfo fileInf = new FileInfo(sourceFile);
string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
// Provide the WebPermission Credintials
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// By default KeepAlive is true, where the control connection is not closed
// after a command is executed.
reqFTP.KeepAlive = false;
// Specify the command to be executed.
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// Specify the data transfer type.
reqFTP.UseBinary = true;
// Notify the server about the size of the uploaded file
reqFTP.ContentLength = fileInf.Length;
// The buffer size is set to 2kb
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
FileStream fs = fileInf.OpenRead();
//try
//{
// Stream to which the file to be upload is written
Stream strm = reqFTP.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, buffLength);
// Until Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
//}
//catch (Exception ex)
//{
// Console.Write(ex.Message, "Upload Error");
//}
}
I found the answer for the problem. I was using SFTP server instead of FTP the code was entirely different.
So I changed the code.
using Renci.SshNet;
public static void UploadSFTPFile()
{
_SftpDetails = ReadIniFile(IniFilePath, "Sftp_Settings", SftpDetails);
string sourcefile = System.IO.Path.Combine(filepath, filename);
string destinationpath = _SftpDetails["SftpDestinationFolder"];
string host = _SftpDetails["Host"];
string username = _SftpDetails["UserName"];
string password = _SftpDetails["Password"];
int port = Convert.ToInt32(_SftpDetails["Port"]); //Port 22 is defaulted for SFTP upload
try
{
using (SftpClient client = new SftpClient(host, port, username, password))
{
client.Connect();
client.ChangeDirectory(destinationpath);
using (FileStream fs = new FileStream(sourcefile, FileMode.Open))
{
client.BufferSize = 4 * 1024;
client.UploadFile(fs, Path.GetFileName(sourcefile));
}
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
return;
}
}
you have to install .sshNet from the NuGet Package Manager
I'm not sure why my file is corrupted. I'm not using StreamReader which has been a common problem that most have had. It uploads successfully I just can't seem to find the issue on why the file is corrupted even after searching through the various solved stack overflow questions.
public ActionResult UploadFtpFile(HttpPostedFileBase promoImgFile)
{
bool isSavedSuccessfully = true;
string fileName = null;
string completeDPath = "xxxxx";
string username = "xxxx";
string password = "xxxxx";
FtpWebRequest ftpClient;
FtpWebRequest ftpRequest;
List<string> directories = new List<string>();
try
{
foreach (string fileItemName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileItemName];
fileName = file.FileName;
if (file != null && file.ContentLength > 0)
{
//Create FtpWebRequest object
ftpClient = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + completeDPath + "/" + fileName));
//Set request method
ftpClient.Method = WebRequestMethods.Ftp.UploadFile;
//Set Credentials
ftpClient.Credentials = new NetworkCredential(username, password);
//Opens a file to read
Stream objFile = file.InputStream;
//By default KeepAlive is true, where the control connection is not closed after a command is executed.
ftpClient.KeepAlive = true;
//Set the data transfer type
ftpClient.UseBinary = true;
//Set content length
ftpClient.ContentLength = file.ContentLength;
//Get Stream of the file
Stream objStream = ftpClient.GetRequestStream();
byte[] buffer = new byte[objFile.Length];
//Write file content
objStream.Write(buffer, 0, buffer.Length);
objStream.Close();
objFile.Close();
}
}
}
catch(Exception ex)
{
throw ex;
isSavedSuccessfully = false;
}
//return Json(new { promoImgFile = directories });
return RedirectToAction("Index", "Home", new { promoImgFile = directories });
}
It's this line right here:
Stream objFile = file.InputStream;
Years of learning, I figured out one thing that works:
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
Then work off the MemoryStream.
Example (for text)
Docs: MSDN
The important part for your issue:
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();
Example (for an image)
byte [] imageData = File.ReadAllBytes(imageSource);
request.ContentLength = imageData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(imageData, 0, imageData.Length);
requestStream.Close();
I have some PDFs stored in S3 and I'm trying to make a link that will download them. This is the method that I have so far:
public virtual ActionResult DownloadPDF(string filename)
{
string secretKey = this.UnitOfWork.ApplicationSettingRepository.GetOrCreateByName<string>("StorageProvider_AmazonS3_SecretKey");
string accessKey = this.UnitOfWork.ApplicationSettingRepository.GetOrCreateByName<string>("StorageProvider_AmazonS3_AccessKey");
var bucket = this.UnitOfWork.ApplicationSettingRepository.GetOrCreateByName<string>("StorageProvider_AmazonS3_BucketName");
var serviceUrl = this.UnitOfWork.ApplicationSettingRepository.GetOrCreateByName<string>("StorageProvider_AmazonS3_ServiceUrl");
AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = serviceUrl;
var client = Amazon.AWSClientFactory.CreateAmazonS3Client(
accessKey,
secretKey,
config
);
GetObjectRequest request = new GetObjectRequest();
request.BucketName = bucket;
request.Key = "userfiles/MSD IMAGES/ProductDocumentation/" + filename;
GetObjectResponse response = client.GetObject(request);
response.WriteResponseStreamToFile("\\Downloads\\" + filename);
}
I got that method from this documentation here but I want to download the download to show in the browser, and go to the standard downloads folder. I created this method previously for downloading csv files:
var csv = new StringBuilder();
csv.AppendLine("col1,col2,col3");
var bytes = Encoding.UTF8.GetBytes(csv.ToString());
var response = new FileContentResult(bytes, "text/csv");
response.FileDownloadName = fileName;
return response;
I tried doing the same thing with the S3 file:
GetObjectResponse response = client.GetObject(request);
// response.WriteResponseStreamToFile("\\Downloads\\" + filename);
var bytes = Encoding.UTF8.GetBytes(response.ToString());
var download = new FileContentResult(bytes, "application/pdf");
download.FileDownloadName = filename;
return download;
it downloads a file, but the pdf doesn't work (it fails to load). How do I download the file that I got from S3?
Here's the working solution I came up with:
GetObjectResponse response = client.GetObject(request);
using (Stream responseStream = response.ResponseStream)
{
var bytes = ReadStream(responseStream);
var download = new FileContentResult(bytes, "application/pdf");
download.FileDownloadName = filename;
return download;
}
public static byte[] ReadStream(Stream responseStream)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
you would need to do something like the following
int byteCount
byte[] buffer = new byte[2048]; // read in chunks of 2KB
Stream responseStream= Response.GetResponseStream();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
while ((byteCount = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, byteCount);
}
Response.Flush();
Response.Close();
Response.End();
I have a methode that copy folder structure from ftp to local folder and then copy all files that consists in them:
public void CreateDirectories()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Url);
request.Credentials = new NetworkCredential(Login, Pass);
request.Method = WebRequestMethods.Ftp.ListDirectory;
string soursePath = #"L:\Test";
StreamReader streamReader = new StreamReader(request.GetResponse().GetResponseStream());
string directoryName = streamReader.ReadLine();
while (directoryName != null)
{
//Create directories structure
if (directoryName.StartsWith("I") && !directoryName.Contains("p"))
{
string newPath = System.IO.Path.Combine(soursePath, directoryName);
if (!System.IO.Directory.Exists(newPath))
{
System.IO.Directory.CreateDirectory(newPath);
//get file list and invoke DownLoad(string directoryName, string fileName)
FtpWebRequest fileRequest = (FtpWebRequest)WebRequest.Create(Url + directoryName + "/");
fileRequest.Credentials = new NetworkCredential(Login, Pass);
fileRequest.Method = WebRequestMethods.Ftp.ListDirectory;
StreamReader fileStreamReader = new StreamReader(fileRequest.GetResponse().GetResponseStream());
string fileName = fileStreamReader.ReadLine();
while (fileName != null)
{
DownLoad(directoryName, fileName);
fileName = streamReader.ReadLine();
}
}
}
directoryName = streamReader.ReadLine();
}
request = null;
streamReader = null;
}
and the methode that copy current file:
public void DownLoad(string directoryName, string fileName)
{
string localPath = #"L:\Test\" + directoryName;
FtpWebRequest requestFileDownload = (FtpWebRequest)WebRequest.Create("ftp://ftp.equip.me/prod/" + directoryName + "/" + fileName);
requestFileDownload.Credentials = new NetworkCredential(Login, Pass);
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse responseFileDownload = (FtpWebResponse)requestFileDownload.GetResponse();
Stream responseStream = responseFileDownload.GetResponseStream();
FileStream writeStream = new FileStream(localPath + "\\" + fileName, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
responseStream.Close();
writeStream.Close();
requestFileDownload = null;
responseFileDownload = null;
}
But in line Stream responseStream = responseFileDownload.GetResponseStream(); it stop for nearly 40 seconds and then throw an exeption of timeout, and no one file has not been saved (file is small - 50 kb)
The first thing that you should try is to turn passive mode off since this is automatically blocked by most firewalls, but is the default mode of operation for ftpWebRequest.
Just below this line:
requestFileDownload.Method = WebRequestMethods.Ftp.DownloadFile;
and this one:
requestFileDownload.UsePassive = false;
Finding some problems copying a zip file from an FTP location. It is just copying and empty file so I think there is something wrong with my use of StreamReader or StreamWriter.
Here is the code:
//read through directory details response
string line = reader.ReadLine();
while (line != null)
{
if (line.EndsWith("zip")) //"d" = dir don't need "." or ".." dirs
{
FtpWebRequest downloadRequest = (FtpWebRequest)FtpWebRequest.Create("ftp://" + ftpHost + line); //new Uri("ftp://" + ftpServerIP + DestinationFolder + fileInf.Name));
downloadRequest.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FilesUser"], ConfigurationManager.AppSettings["FilesPass"]);
downloadRequest.KeepAlive = false;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
string folderToWrite = HttpContext.Current.Server.MapPath("~/Routing/RoutingFiles/");
string folderToSave = HttpContext.Current.Server.MapPath("~/Routing/");
StreamReader downloadRequestReader = new StreamReader(downloadRequest.GetResponse().GetResponseStream());
DirectoryInfo downloadDirectory = new DirectoryInfo(folderToWrite);
FileInfo file = new FileInfo(Path.Combine(downloadDirectory.FullName, line));
if (!file.Exists)
{
StreamWriter writer = new StreamWriter(Path.Combine(folderToWrite, line), false);
writer.Write(downloadRequestReader.ReadToEnd());
using (var downloadResponseStream = response.GetResponseStream())
{
}
}
}
}
By the time it gets to the bottom of that section, the file has been copied but is empty so I don't think I'm reading the stream correctly for a zip file. Anyone any ideas? I've seen talk of FileStream being better for downloading Zip files, but I couldn't get that to work either.
Thanks.
Here is an example that downloads a file from an ftp.
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddr + "test.zip");
request.Credentials = new NetworkCredential(userName, password);
request.UseBinary = true; // Use binary to ensure correct dlv!
request.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writer = new FileStream("test.zip", FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
responseStream.Close();
response.Close();
writer.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Edit I'm sorry for the error in previous code.
When correcting my previous code I found the following resource useful: example