用C#通过HTTP POST发送文件

我一直在寻找和阅读,并没有任何罚款任何真正有用的东西。

我正在写一个小的C#赢得应用程序,允许用户发送文件到Web服务器,而不是通过FTP,但通过HTTP使用POST。 把它想象成一个Web窗体,但在Windows应用程序上运行。

我有我的HttpWebRequest对象创build使用这样的事情

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest 

并设置MethodContentTypeContentLength属性。 但是,我可以走多远。

这是我的一段代码:

 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) { } 

所以我的问题是基本上我怎么可以发送一个fie(文本文件,图像,audio等)与C#通过HTTP POST。

谢谢!

使用.NET 4.5(或通过从NuGet添加Microsoft.Net.Http包的.NET 4.0)有一个更简单的方法来模拟表单请求。 这里是一个例子:

 private 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 = client.PostAsync(actionUrl, formData).Result; if (!response.IsSuccessStatusCode) { return null; } return response.Content.ReadAsStreamAsync().Result; } } 

发送原始文件:

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

如果你想用<input type="file"/>来模拟一个浏览器表单,那就更难了。 看到这个答案的多部分/forms – 数据的答案。

您需要将文件写入请求stream:

 using (var reqStream = req.GetRequestStream()) { reqStream.Write( ... ) // write the bytes of the file } 

我遇到了同样的问题,下面的代码在这个问题上得到了很好的回答:

 //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's 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; } 

对我来说, client.UploadFile仍然包含在一个多部分请求的内容,所以我必须这样做:

 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); } } 

从字节数组中发布文件:

 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); } } } 
  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(); } }