download file from remote server asp.net - asp.net

I am trying to download file from a file hosting server, using my username and password through my own website.
I already achieve the possibility to connect and download the file, with the code attached below.
my problem is this code doesn't support resume of download and my download manager isn't able to open more then one connection to the remote site ,so the speed is very low(the remote site Of course is supporting those features)
my main goal is to let me download this file with full speed and with the ability to resume the download in any Second.
this is the code
//the login method
ASCIIEncoding encoding = new ASCIIEncoding();
string url = "RemoteServerLoginPage/loginPage";
string postVariables = "id=myIdToTheServer";
postVariables += "&password=MyPasswordToTheServer";
// create the POST request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
CookieContainer cookies = new CookieContainer();
webRequest.CookieContainer = cookies;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = postVariables.Length;
byte[] data = encoding.GetBytes(postVariables);
Stream newStream = webRequest.GetRequestStream();
// Send the request
newStream.Write(data, 0, data.Length);
HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
using (Stream stream = resp.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
String responseString = reader.ReadToEnd();
}
//after login get the file with thr right cookies
string url2 = "UrlOfRemoteServerFileAdress/filename.rar";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url2);
req.CookieContainer = cookies;
HttpWebResponse resp2 = (HttpWebResponse)req.GetResponse();
////Initialize the output stream
Response.Clear();
Response.AppendHeader("Content-Disposition:", "attachment; filename=myfile.rar");
Response.AppendHeader("Content-Length:", "bytes");
Response.AppendHeader("Connection:", "Keep-Alive");
Response.ContentType = "application/octet-stream";
Response.AppendHeader("AcceptRanges", resp2.ContentLength.ToString());
const int BufferLength = 4 * 1024 * 1024;
byte[] byteBuffer = new byte[BufferLength];
Stream rs = req.GetResponse().GetResponseStream();
int len = 0;
while ((len = rs.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
if (len < BufferLength)
{
Response.BinaryWrite(byteBuffer.Take(len).ToArray());
}
else
{
Response.BinaryWrite(byteBuffer);
}
Response.Flush();
}

Related

files not uploading to FTP Server [duplicate]

I try upload a file to an FTP-server with C#. The file is uploaded but with zero bytes.
private void button2_Click(object sender, EventArgs e)
{
var dirPath = #"C:/Documents and Settings/sander.GD/Bureaublad/test/";
ftp ftpClient = new ftp("ftp://example.com/", "username", "password");
string[] files = Directory.GetFiles(dirPath,"*.*");
var uploadPath = "/httpdocs/album";
foreach (string file in files)
{
ftpClient.createDirectory("/test");
ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
}
if (string.IsNullOrEmpty(txtnaam.Text))
{
MessageBox.Show("Gelieve uw naam in te geven !");
}
}
The existing answers are valid, but why re-invent the wheel and bother with lower level WebRequest types while WebClient already implements FTP uploading neatly:
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}
Easiest way
The most trivial way to upload a file to an FTP server using .NET framework is using WebClient.UploadFile method:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
var url = "ftp://ftp.example.com/remote/path/file.zip";
client.UploadFile(url, #"C:\local\path\file.zip");
Advanced options
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, active mode, transfer resuming, progress monitoring, etc), use FtpWebRequest. Easy way is to just copy a FileStream to an FTP stream using Stream.CopyTo:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
Progress monitoring
If you need to monitor an upload progress, you have to copy the contents by chunks yourself:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ftpStream.Write(buffer, 0, read);
Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see C# example at:
How can we show progress bar for upload with FtpWebRequest
Uploading folder
If you want to upload all files from a folder, see
Upload directory of files to FTP server using WebClient.
For a recursive upload, see
Recursive upload to FTP server in C#
.NET 5 Guide
async Task<FtpStatusCode> FtpFileUploadAsync(string ftpUrl, string userName, string password, string filePath)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(userName, password);
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (Stream requestStream = request.GetRequestStream())
{
await fileStream.CopyToAsync(requestStream);
}
using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
{
return response.StatusCode;
}
}
.NET Framework
public void UploadFtpFile(string folderName, string fileName)
{
FtpWebRequest request;
string folderName;
string fileName;
string absoluteFileName = Path.GetFileName(fileName);
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/{2}", "127.0.0.1", folderName, absoluteFileName))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = 1;
request.UsePassive = 1;
request.KeepAlive = 1;
request.Credentials = new NetworkCredential(user, pass);
request.ConnectionGroupName = "group";
using (FileStream fs = File.OpenRead(fileName))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
}
}
How to use
UploadFtpFile("testFolder", "E:\\filesToUpload\\test.img");
use this in your foreach
and you only need to create folder one time
to create a folder
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/", "127.0.0.1", "testFolder"))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)request.GetResponse();
The following works for me:
public virtual void Send(string fileName, byte[] file)
{
ByteArrayToFile(fileName, file);
var request = (FtpWebRequest) WebRequest.Create(new Uri(ServerUrl + fileName));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UsePassive = false;
request.Credentials = new NetworkCredential(UserName, Password);
request.ContentLength = file.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(file, 0, file.Length);
requestStream.Close();
var response = (FtpWebResponse) request.GetResponse();
if (response != null)
response.Close();
}
You can't read send the file parameter in your code as it is only the filename.
Use the following:
byte[] bytes = File.ReadAllBytes(dir + file);
To get the file so you can pass it to the Send method.
public static void UploadFileToFtp(string url, string filePath, string username, string password)
{
var fileName = Path.GetFileName(filePath);
var request = (FtpWebRequest)WebRequest.Create(url + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
using (var fileStream = File.OpenRead(filePath))
{
using (var requestStream = request.GetRequestStream())
{
fileStream.CopyTo(requestStream);
requestStream.Close();
}
}
var response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload done: {0}", response.StatusDescription);
response.Close();
}
In the first example must change those to:
requestStream.Flush();
requestStream.Close();
First flush and after that close.
This works for me,this method will SFTP a file to a location within your network.
It uses SSH.NET.2013.4.7 library.One can just download it for free.
//Secure FTP
public void SecureFTPUploadFile(string destinationHost,int port,string username,string password,string source,string destination)
{
ConnectionInfo ConnNfo = new ConnectionInfo(destinationHost, port, username, new PasswordAuthenticationMethod(username, password));
var temp = destination.Split('/');
string destinationFileName = temp[temp.Count() - 1];
string parentDirectory = destination.Remove(destination.Length - (destinationFileName.Length + 1), destinationFileName.Length + 1);
using (var sshclient = new SshClient(ConnNfo))
{
sshclient.Connect();
using (var cmd = sshclient.CreateCommand("mkdir -p " + parentDirectory + " && chmod +rw " + parentDirectory))
{
cmd.Execute();
}
sshclient.Disconnect();
}
using (var sftp = new SftpClient(ConnNfo))
{
sftp.Connect();
sftp.ChangeDirectory(parentDirectory);
using (var uplfileStream = System.IO.File.OpenRead(source))
{
sftp.UploadFile(uplfileStream, destinationFileName, true);
}
sftp.Disconnect();
}
}
publish date: 06/26/2018
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp
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.
byte[] fileContents;
using (StreamReader sourceStream = new StreamReader("testfile.txt"))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine($"Upload File Complete, status
{response.StatusDescription}");
}
}
}
}
Best way I've found is FluentFtp
You can find the repo here:
https://github.com/robinrodricks/FluentFTP
and the quickstart example here:
https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example.
And actually the WebRequest class recommended by a few people here, is not recommended by Microsoft anymore, check out this page:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-5.0
// create an FTP client and specify the host, username and password
// (delete the credentials to use the "anonymous" account)
FtpClient client = new FtpClient("123.123.123.123", "david", "pass123");
// connect to the server and automatically detect working FTP settings
client.AutoConnect();
// upload a file and retry 3 times before giving up
client.RetryAttempts = 3;
client.UploadFile(#"C:\MyVideo.mp4", "/htdocs/big.txt",
FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
// disconnect! good bye!
client.Disconnect();
I have observed that -
FtpwebRequest is missing.
As the target is FTP, so the NetworkCredential required.
I have prepared a method that works like this, you can replace the value of the variable ftpurl with the parameter TargetDestinationPath. I had tested this method on winforms application :
private void UploadProfileImage(string TargetFileName, string TargetDestinationPath, string FiletoUpload)
{
//Get the Image Destination path
string imageName = TargetFileName; //you can comment this
string imgPath = TargetDestinationPath;
string ftpurl = "ftp://downloads.abc.com/downloads.abc.com/MobileApps/SystemImages/ProfileImages/" + imgPath;
string ftpusername = krayknot_DAL.clsGlobal.FTPUsername;
string ftppassword = krayknot_DAL.clsGlobal.FTPPassword;
string fileurl = FiletoUpload;
FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl);
ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
ftpClient.UseBinary = true;
ftpClient.KeepAlive = true;
System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
ftpClient.ContentLength = fi.Length;
byte[] buffer = new byte[4097];
int bytes = 0;
int total_bytes = (int)fi.Length;
System.IO.FileStream fs = fi.OpenRead();
System.IO.Stream rs = ftpClient.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
//fs.Flush();
fs.Close();
rs.Close();
FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
string value = uploadResponse.StatusDescription;
uploadResponse.Close();
}
Let me know in case of any issue, or here is one more link that can help you:
https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx

Problems with downloading pdf file from web api service

I'm trying to set up a web api service that searches for a .pdf file in a directory and returns the file if it's found.
The controller
public class ProductsController : ApiController
{
[HttpPost]
public HttpResponseMessage Post([FromBody]string certificateId)
{
string fileName = certificateId + ".pdf";
var path = #"C:\Certificates\20487A" + fileName;
//check the directory for pdf matching the certid
if (File.Exists(path))
{
//if there is a match then return the file
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(path, FileMode.Open);
stream.Position = 0;
result.Content = new StreamContent(stream);
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = fileName };
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition.FileName = fileName;
return result;
}
else
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.Gone);
return result;
}
}
}
I'm calling the service with the following code
private void GetCertQueryResponse(string url, string serial)
{
string encodedParameters = "certificateId=" + serial.Replace(" ", "");
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.AllowAutoRedirect = false;
byte[] bytedata = Encoding.UTF8.GetBytes(encodedParameters);
httpRequest.ContentLength = bytedata.Length;
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytedata, 0, bytedata.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
byte[] bytes = null;
using (Stream stream = response.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = stream.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (stream.CanRead && count > 0);
ms.Position = 0;
bytes = ms.ToArray();
}
var filename = serial + ".pdf";
Response.ContentType = "application/pdf";
Response.Headers.Add("Content-Disposition", "attachment; filename=\"" + filename + "\"");
Response.BinaryWrite(bytes);
}
}
This appears to be working in the sense that the download file dialogue is shown with the correct file name and size etc, but the download takes only a couple of seconds (when the file sizes are >30mb) and the files are corrupt when I try to open them.
Any ideas what I'm doing wrong?
Your code looks similar to what Ive used in the past, but below is what I typically use:
Response.AddHeader("content-length", myfile.Length.ToString())
Response.AddHeader("content-disposition", "inline; filename=MyFilename")
Response.AddHeader("Expires", "0")
Response.AddHeader("Pragma", "Cache")
Response.AddHeader("Cache-Control", "private")
Response.ContentType = "application/pdf"
Response.BinaryWrite(finalForm)
I post this for 2 reasons. One, add the content-length header, you may have to indicate how large the file is so the application waits for the whole response.
If that doesn't fix it. Set a breakpoint, does the byte array content the appropriate length (aka, 30 million bytes for a 30 MB file)? Have you used fiddler to see how much content is coming back over the HTTP call?

curl Request with ASP.NET

I have read some other posts on Stack but I can't get this to work. It works fine on my when I run the curl command in git on my windows machine but when I convert it to asp.net it's not working:
private void BeeBoleRequest()
{
string url = "https://mycompany.beebole-apps.com/api";
WebRequest myReq = WebRequest.Create(url);
string username = "e26f3a722f46996d77dd78c5dbe82f15298a6385";
string password = "x";
string usernamePassword = username + ":" + password;
CredentialCache mycache = new CredentialCache();
mycache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
myReq.Credentials = mycache;
myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));
WebResponse wr = myReq.GetResponse();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
Response.Write(content);
}
This is the BeeBole API. Its pretty straight fwd. http://beebole.com/api but I am getting a following 500 error when I run the above:
The remote server returned an error: (500) Internal Server Error.
The default HTTP method for WebRequest is GET. Try setting it to POST, as that's what the API is expecting
myReq.Method = "POST";
I assume you are posting something. As a test, I'm going to post the same data from their curl example.
string url = "https://YOUR_COMPANY_HERE.beebole-apps.com/api";
string data = "{\"service\":\"absence.list\", \"company_id\":3}";
WebRequest myReq = WebRequest.Create(url);
myReq.Method = "POST";
myReq.ContentLength = data.Length;
myReq.ContentType = "application/json; charset=UTF-8";
string usernamePassword = "YOUR API TOKEN HERE" + ":" + "x";
UTF8Encoding enc = new UTF8Encoding();
myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(enc.GetBytes(usernamePassword)));
using (Stream ds = myReq.GetRequestStream())
{
ds.Write(enc.GetBytes(data), 0, data.Length);
}
WebResponse wr = myReq.GetResponse();
Stream receiveStream = wr.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
Response.Write(content);

How to pass value in url using web request GET method asp.net

Am new to .Net and web service..i like to pass id through url..how to do that?whether it was done post or get method?guide me
string url = "http://XXXXX//"+id=22;
WebRequest request = WebRequest.Create(url);
request.Proxy.Credentials = new NetworkCredential(xxxxx);
request.Credentials = CredentialCache.DefaultCredentials;
//add properties
request.Method = "GET";
request.ContentType = "application/json";
//convert
byte[] byteArray = Encoding.UTF8.GetBytes(data);
request.ContentLength = byteArray.Length;
//post data
Stream streamdata = request.GetRequestStream();
streamdata.Write(byteArray, 0, byteArray.Length);
streamdata.Close();
//response
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
response.Close();
If you just want to build the URL with parameters (ref: Query String) then you can simply do:
string url = string.Format("http://www.google.com/?id={0}",22);
You can check this url, Passing variables between pages using QueryString at Code Project

convert HTTP request code to HTTPS request code

I have got following code witch are sending xml file on HTTP protocol and getting response back as xml file from webserver and its working fine with HTTP protocol, but now i need to send such a XML file to HTTPS protocol (not http) and need to get response as xml file from it. the code to send xml file and get response from HTTP is :
string targetUri = "http://www.hostelspoint.com/xml/xml.php"; /*this will be like: "https://www.hostelspoint.com/xml/xml.php"*/
System.Xml.XmlDocument reqDoc = new System.Xml.XmlDocument();
reqDoc.Load(Server.MapPath("~\\getdetail.xml"));
string formParameterName = "OTA_request";
string xmlData = reqDoc.InnerXml;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(targetUri);
string sendString = formParameterName + "=" + HttpUtility.UrlEncode(xmlData);
//string sendString = HttpUtility.UrlEncode(xmlData);
byte[] byteStream;
byteStream = System.Text.Encoding.UTF8.GetBytes(sendString);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteStream.LongLength;
using (Stream writer = request.GetRequestStream())
{
writer.Write(byteStream, 0, (int)request.ContentLength);
writer.Flush();
}
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
string respStr = "";
if (request.HaveResponse)
{
if (resp.StatusCode == HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.Accepted)
{
StreamReader respReader = new StreamReader(resp.GetResponseStream());
respStr = respReader.ReadToEnd(); // get the xml result in the string object
XmlDocument doc = new XmlDocument();
doc.LoadXml(respStr);
Label1.Text = doc.InnerXml.ToString();
}
}
There shouldn't be much difference in your code, as HTTP or HTTPS differs only in transport level, not in application level.
What may become a problem here is, if the server certificate used in the targetUri is trusted on your server. In this case the HTTPS identity cannot be verified.

Resources