Is there any class, library or some piece of code which will help me to upload files with HTTPWebrequest?
Edit 2:
I do not want to upload to a WebDAV folder or something like that. I want to simulate a browser, so just like you upload your avatar to a forum or upload a file via form in a web application. Upload to a form which uses a multipart/form-data.
Edit:
WebClient is not cover my requirements, so I'm looking for a solution with HTTPWebrequest.
Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.
Took the code above and fixed because it throws Internal Server Error 500. There are some problems with \r\n badly positioned and spaces etc. Applied the refactoring with memory stream, writing directly to the request stream. Here is the result:
public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc) { log.Debug(string.Format("Uploading {0} to {1}", file, url)); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.KeepAlive = true; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; foreach (string key in nvc.Keys) { rs.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, nvc[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); 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, paramName, file, contentType); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(file, 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(); WebResponse wresp = null; try { wresp = wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); StreamReader reader2 = new StreamReader(stream2); log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd())); } catch(Exception ex) { log.Error("Error uploading file", ex); if(wresp != null) { wresp.Close(); wresp = null; } } finally { wr = null; } }
and sample usage:
NameValueCollection nvc = new NameValueCollection(); nvc.Add("id", "TTR"); nvc.Add("btn-submit-photo", "Upload"); HttpUploadFile("http://your.server.com/upload", @"C:\test\test.jpg", "file", "image/jpeg", nvc);
It could be extended to handle multiple files or just call it multiple times for each file. However it suits your needs.
I was looking for something like this, Found in : http://bytes.com/groups/net-c/268661-how-upload-file-via-c-code (modified for correctness):
public static string UploadFilesToRemoteUrl(string url, string[] files, NameValueCollection formFields = null) { string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); request.ContentType = "multipart/form-data; boundary=" + boundary; request.Method = "POST"; request.KeepAlive = true; Stream memStream = new System.IO.MemoryStream(); var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--"); string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}"; if (formFields != null) { foreach (string key in formFields.Keys) { string formitem = string.Format(formdataTemplate, key, formFields[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); memStream.Write(formitembytes, 0, formitembytes.Length); } } string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n"; for (int i = 0; i < files.Length; i++) { memStream.Write(boundarybytes, 0, boundarybytes.Length); var header = string.Format(headerTemplate, "uplTheFile", files[i]); var headerbytes = System.Text.Encoding.UTF8.GetBytes(header); memStream.Write(headerbytes, 0, headerbytes.Length); using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read)) { var buffer = new byte[1024]; var bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { memStream.Write(buffer, 0, bytesRead); } } } memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); request.ContentLength = memStream.Length; using (Stream requestStream = request.GetRequestStream()) { memStream.Position = 0; byte[] tempBuffer = new byte[memStream.Length]; memStream.Read(tempBuffer, 0, tempBuffer.Length); memStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); } using (var response = request.GetResponse()) { Stream stream2 = response.GetResponseStream(); StreamReader reader2 = new StreamReader(stream2); return reader2.ReadToEnd(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With