[英]Issue while posting MultipartFormData c#
Sorry for this question, I know there are too many discussion already did on the same topic, I tried everything but I am not able to identify the exact issue. 对不起这个问题,我知道关于同一主题的讨论已经太多了,我尝试了一切,但我无法确定确切的问题。 So I need some input from experts.
所以我需要专家的一些意见。
Requirement: Its very simple, we to post two text fieds as string and one xml file. 要求:非常简单,我们将两个文本fieds发布为字符串和一个xml文件。
Below the sample network call trace when I am doing the same using browser. 在我使用浏览器执行相同操作时,示例网络调用跟踪下方。
C# code to acheive the same. C#代码实现相同。
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;
}
The response is "Bad Request 400". 响应是“错误请求400”。 Please provide comments on this.
请提供意见。
The MultipartFormDataContent
doesn't know the boundary. MultipartFormDataContent
不知道边界。 You only set the boundary in the headers. 您只在标题中设置边界。
Use a constructor, that includes a boundary, read more here: https://msdn.microsoft.com/en-us/library/hh138232(v=vs.118).aspx 使用包含边界的构造函数,在此处阅读更多内容: https : //msdn.microsoft.com/en-us/library/hh138232(v = vs.118).aspx
I've been successfully using this helper class for creating HttpMultipartPostReuest
for a long time. 我已成功使用这个助手类长时间创建
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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.