2016-04-08 85 views
1

對不起,對於這個問題,我知道有太多的討論已經做了同一主題,我嘗試了一切,但我無法確定確切的問題。所以我需要一些專家的意見。發佈時發佈MultipartFormData c#

要求:它非常簡單,我們發佈兩個文本fieds作爲字符串和一個xml文件。

當我使用瀏覽器做同樣的網絡調用跟蹤示例。

Browser Call

C#代碼acheive相同。

using (HttpClient http = new HttpClient()) 
     { 
      http.BaseAddress = new Uri("http://**.168.215.***"); 
      http.DefaultRequestHeaders.Add("User-Agent", 
       "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36"); 
      http.DefaultRequestHeaders.Add("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundarydsads"); 
      MultipartFormDataContent content = new MultipartFormDataContent(); 
      HttpContent datasource = new StringContent("test", Encoding.UTF8); 
      HttpContent feedtype = new StringContent("metadata-and-url", Encoding.UTF8); 
      string xmlText = File.ReadAllText(fi.FullName); 
      HttpContent data = new ByteArrayContent(File.ReadAllBytes(fi.FullName)); 
      content.Add(datasource, "datasource"); 
      content.Add(feedtype, "feedtype"); 
      content.Add(data, "data", "text.xml"); 

      var response = http.PostAsync("/xmlfeed", content).Result; 

     } 

答案是「Bad Request 400」。 請提供意見。

+0

HTTP 4xx錯誤是用戶錯誤 – isxaker

回答

0

我已經成功地使用這種輔助類的很長一段時間來創建HttpMultipartPostReuest

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Text; 

namespace GeneralHelpers.Web 
{ 

    public class HttpMultipartPostReuest 
    { 

     private const string FileParamContentDisposition = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n"; 
     private const string GeneralParamContentDisposition = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; 
     private const string MultipartContent = "multipart/form-data; boundary="; 

     private readonly string _boundary; 
     private readonly byte[] _boundaryBytes; 
     private readonly string _contentType; 
     private readonly Encoding _encoding = Encoding.UTF8; 
     private readonly HttpWebRequest _request; 

     public string Boundary { get { return this._boundary; } } 

     public string ContentType { get { return this._contentType; } } 

     public HttpMultipartPostReuest(string url, Dictionary<string, object> postParameters) 
     { 
      this._boundary = HttpMultipartPostReuest.GenerateBoundary(); 
      this._boundaryBytes = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}\r\n", this._boundary)); 
      this._contentType = HttpMultipartPostReuest.MultipartContent + this._boundary; 

      this._request = WebRequest.Create(url) as HttpWebRequest; 
      if (this._request == null) 
      { 
       throw new NullReferenceException("request is not a http request"); 
      } 

      byte[] formData = this.GetMultipartFormData(postParameters); 

      // Set up the request properties. 
      this._request.Method = WebRequestMethods.Http.Post; 
      this._request.ContentType = this._contentType; 
      this._request.ContentLength = formData.Length; 
      this._request.Credentials = System.Net.CredentialCache.DefaultCredentials; 

      // Send the form data to the request. 
      using (Stream requestStream = this._request.GetRequestStream()) 
      { 
       requestStream.Write(formData, 0, formData.Length); 
       requestStream.Close(); 
      } 
     } 

     private static string GenerateBoundary() 
     { 
      return string.Format("---------------------------{0}", DateTime.Now.Ticks.ToString("x")); 
     } 

     public WebResponse GetResponce() 
     { 
      return this._request.GetResponse(); 
     } 

     private byte[] GetMultipartFormData(Dictionary<string, object> postParameters) 
     { 
      using (Stream formDataStream = new MemoryStream()) 
      { 
       foreach (var param in postParameters) 
       { 
        //always wtiring boundary 
        formDataStream.Write(this._boundaryBytes, 0, this._boundaryBytes.Length); 

        FileParameter value = param.Value as FileParameter; 
        if (value != null) 
        { 
         FileParameter fileToUpload = value; 

         // Add just the first part of this param, since we will write the file data directly to the Stream 
         string header = string.Format(HttpMultipartPostReuest.FileParamContentDisposition, param.Key, fileToUpload.FileName ?? param.Key, 
          fileToUpload.ContentType); 

         formDataStream.Write(this._encoding.GetBytes(header), 0, this._encoding.GetByteCount(header)); 

         // Write the file data directly to the Stream, rather than serializing it to a string. 
         formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); 
        } 
        else 
        { 
         string postData = string.Format(HttpMultipartPostReuest.GeneralParamContentDisposition, param.Key, param.Value); 
         formDataStream.Write(this._encoding.GetBytes(postData), 0, this._encoding.GetByteCount(postData)); 
        } 
       } 

       // Add the end of the request. Start with a newline 
       string footer = "\r\n--" + this._boundary + "--\r\n"; 
       formDataStream.Write(this._encoding.GetBytes(footer), 0, this._encoding.GetByteCount(footer)); 

       // Dump the Stream into a byte[] 
       formDataStream.Position = 0; 
       byte[] formData = new byte[formDataStream.Length]; 
       formDataStream.Read(formData, 0, formData.Length); 
       formDataStream.Close(); 

       return formData; 
      } 
     } 

    } 

     public class FileParameter 
    { 
     private const string DefaultContentType = "application/octet-stream"; 

     private readonly string _contentType; 
     private readonly byte[] _file; 
     private readonly string _fileName; 

     public string ContentType { get { return this._contentType; } } 
     public byte[] File { get { return this._file; } } 
     public string FileName { get { return this._fileName; } } 

     private FileParameter() 
     { 
      this._contentType = FileParameter.DefaultContentType; 
     } 

     public FileParameter(byte[] file) : this(file, FileParameter.DefaultContentType) 
     { 
     } 

     public FileParameter(byte[] file, string filename) : this(file, filename, FileParameter.DefaultContentType) 
     { 
     } 

     public FileParameter(string path, string fileName) : this() 
     { 
      this._file = FileParameter.LoadFile(path); 
      this._fileName = fileName; 
     } 

     public FileParameter(string path, string fileName, string contentType) 
      : this() 
     { 
      this._file = FileParameter.LoadFile(path); 
      this._fileName = fileName; 
      this._contentType = contentType; 
     } 

     public FileParameter(byte[] file, string fileName, string contentType) 
     { 
      this._file = file; 
      this._fileName = fileName; 
      if (!string.IsNullOrWhiteSpace(contentType)) 
      { 
       this._contentType = contentType; 
      } 
      { 
       this._contentType = FileParameter.DefaultContentType; 
      } 
     } 

     private static byte[] LoadFile(string path) 
     { 
      byte[] data; 
      // Read file data 
      using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
      { 
       data = new byte[fs.Length]; 
       fs.Read(data, 0, data.Length); 
      } 

      return data; 
     } 

    } 

}