Send file via HTTP POST using C #

I searched and read about it, and could not distinguish anything.

I am writing a small search application in C # that allows you to send files to a web server, not via FTP, but through HTTP using POST. Think of it as a web form, but work in a Windows application.

I have an HttpWebRequest object created using something like this

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest 

and set the Method , ContentType and ContentLength . But this is far I can go.

This is my piece of code:

 HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest; req.KeepAlive = false; req.Method = "POST"; req.Credentials = new NetworkCredential(user.UserName, user.UserPassword); req.PreAuthenticate = true; req.ContentType = file.ContentType; req.ContentLength = file.Length; HttpWebResponse response = null; try { response = req.GetResponse() as HttpWebResponse; } catch (Exception e) { } 

So my question basically is how can I send fie (text file, image, audio, etc.) using C # via HTTP POST.

Thank!

+88
c # post
Jul 15 '09 at 13:31
source share
8 answers

Using .NET 4.5 (or .NET 4.0 by adding the Microsoft.Net.Http package from NuGet) makes it easy to simulate form requests. Here is an example:

 private async Task<System.IO.Stream> Upload(string actionUrl, string paramString, Stream paramFileStream, byte [] paramFileBytes) { HttpContent stringContent = new StringContent(paramString); HttpContent fileStreamContent = new StreamContent(paramFileStream); HttpContent bytesContent = new ByteArrayContent(paramFileBytes); using (var client = new HttpClient()) using (var formData = new MultipartFormDataContent()) { formData.Add(stringContent, "param1", "param1"); formData.Add(fileStreamContent, "file1", "file1"); formData.Add(bytesContent, "file2", "file2"); var response = await client.PostAsync(actionUrl, formData); if (!response.IsSuccessStatusCode) { return null; } return await response.Content.ReadAsStreamAsync(); } } 
+99
Oct 29 '13 at 17:15
source

Only to send the raw file:

 using(WebClient client = new WebClient()) { client.UploadFile(address, filePath); } 

If you want to emulate a browser form with <input type="file"/> , this is more complicated. See this answer for multipart / form-data answer.

+47
Jul 15 '09 at 13:32
source

For me, client.UploadFile still completed the contents in a multiprocessor request, so I had to do it like this:

 using (WebClient client = new WebClient()) { client.Headers.Add("Content-Type", "application/octet-stream"); using (Stream fileStream = File.OpenRead(filePath)) using (Stream requestStream = client.OpenWrite(new Uri(fileUploadUrl), "POST")) { fileStream.CopyTo(requestStream); } } 
+7
Jul 21 '15 at 9:31 on
source

I had the same problem and this following code answered this problem perfectly:

 //Identificate separator string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); //Encoding byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); //Creation and specification of the request HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); //sVal is id for the webService wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.KeepAlive = true; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; string sAuthorization = "login:password";//AUTHENTIFICATION BEGIN byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(sAuthorization); string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); wr.Headers.Add("Authorization: Basic " + returnValue); //AUTHENTIFICATION END Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; //For the POST format //Writting of the file rs.Write(boundarybytes, 0, boundarybytes.Length); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(Server.MapPath("questions.pdf")); rs.Write(formitembytes, 0, formitembytes.Length); rs.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; string header = string.Format(headerTemplate, "file", "questions.pdf", contentType); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(Server.MapPath("questions.pdf"), FileMode.Open, FileAccess.Read); byte[] buffer = new byte[4096]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, bytesRead); } fileStream.Close(); byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); rs.Write(trailer, 0, trailer.Length); rs.Close(); rs = null; WebResponse wresp = null; try { //Get the response wresp = wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); StreamReader reader2 = new StreamReader(stream2); string responseData = reader2.ReadToEnd(); } catch (Exception ex) { string s = ex.Message; } finally { if (wresp != null) { wresp.Close(); wresp = null; } wr = null; } 
+4
Jun 11 '13 at 15:01
source

You need to write the file to the request stream:

 using (var reqStream = req.GetRequestStream()) { reqStream.Write( ... ) // write the bytes of the file } 
+3
Jul 15 '09 at 13:35
source

To send files as from byte arrays:

 private static string UploadFilesToRemoteUrl(string url, IList<byte[]> files, NameValueCollection nvc) { string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x"); var request = (HttpWebRequest) WebRequest.Create(url); request.ContentType = "multipart/form-data; boundary=" + boundary; request.Method = "POST"; request.KeepAlive = true; var postQueue = new ByteArrayCustomQueue(); var formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}"; foreach (string key in nvc.Keys) { var formitem = string.Format(formdataTemplate, key, nvc[key]); var formitembytes = Encoding.UTF8.GetBytes(formitem); postQueue.Write(formitembytes); } var headerTemplate = "\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/zip\r\n\r\n"; var i = 0; foreach (var file in files) { var header = string.Format(headerTemplate, "file" + i, "file" + i + ".zip"); var headerbytes = Encoding.UTF8.GetBytes(header); postQueue.Write(headerbytes); postQueue.Write(file); i++; } postQueue.Write(Encoding.UTF8.GetBytes("\r\n--" + boundary + "--")); request.ContentLength = postQueue.Length; using (var requestStream = request.GetRequestStream()) { postQueue.CopyToStream(requestStream); requestStream.Close(); } var webResponse2 = request.GetResponse(); using (var stream2 = webResponse2.GetResponseStream()) using (var reader2 = new StreamReader(stream2)) { var res = reader2.ReadToEnd(); webResponse2.Close(); return res; } } public class ByteArrayCustomQueue { private LinkedList<byte[]> arrays = new LinkedList<byte[]>(); /// <summary> /// Writes the specified data. /// </summary> /// <param name="data">The data.</param> public void Write(byte[] data) { arrays.AddLast(data); } /// <summary> /// Gets the length. /// </summary> /// <value> /// The length. /// </value> public int Length { get { return arrays.Sum(x => x.Length); } } /// <summary> /// Copies to stream. /// </summary> /// <param name="requestStream">The request stream.</param> /// <exception cref="System.NotImplementedException"></exception> public void CopyToStream(Stream requestStream) { foreach (var array in arrays) { requestStream.Write(array, 0, array.Length); } } } 
0
Jan 08 '15 at 7:58
source
  public string SendFile(string filePath) { WebResponse response = null; try { string sWebAddress = "Https://www.address.com"; string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(sWebAddress); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.KeepAlive = true; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream stream = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; stream.Write(boundarybytes, 0, boundarybytes.Length); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(filePath); stream.Write(formitembytes, 0, formitembytes.Length); stream.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; string header = string.Format(headerTemplate, "file", Path.GetFileName(filePath), Path.GetExtension(filePath)); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); stream.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[4096]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) stream.Write(buffer, 0, bytesRead); fileStream.Close(); byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); stream.Write(trailer, 0, trailer.Length); stream.Close(); response = wr.GetResponse(); Stream responseStream = response.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream); string responseData = streamReader.ReadToEnd(); return responseData; } catch (Exception ex) { return ex.Message; } finally { if (response != null) response.Close(); } } 
0
Feb 21 '17 at 9:10
source

Using .NET 4.5 attempts to download the POST form file. I tried most of the methods described above, but to no avail. Found a solution here https://www.c-sharpcorner.com/article/upload-any-file-using-http-post-multipart-form-data

But I'm not interested, because I don’t understand why we still have to deal with such low-level programs in these common cases (should be well handled by the framework)

0
Jun 08 '19 at 9:18
source



All Articles