我有一个POST被发送到我设置的ASP.NET Web API端点。我已经记录了传入的请求,它们看起来像这样:
Host: somedomain.net
User-Agent: Jakarta; Commons-HttpClient/3.0.1
--7ZRj4zj5nzTkWtBlwkO5Y4Il-En_uTGP2enCIMn
Content-Disposition: form-data; name="companyId"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
985
--7ZRj4zj5nzTkWtBlwkO5Y4Il-En_uTGP2enCIMn
Content-Disposition: form-data; name="inputFormData"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><response>Response XML Data</response>
--7ZRj4zj5nzTkWtBlwkO5Y4Il-En_uTGP2enCIMn
Content-Disposition: form-data; name="completedAgreement"; filename="48ce7fa4079790440a964815a744d232.zip"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
PK
我不确定如何让ASP.NET识别这一点。我已经尝试使用名称作为参数,它们是空的。
另一家公司控制着POST,所以我无法修改它的发送方式。
答案 0 :(得分:0)
我必须创建一个MultipartStreamProvider来将我的数据拆分为表单数据和文件。
/// <summary>
/// Splits a multipart form post that has form data and files
/// </summary>
public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider
{
private NameValueCollection _formData = new NameValueCollection();
private List<HttpContent> _fileContents = new List<HttpContent>();
// Set of indexes of which HttpContents we designate as form data
private Collection<bool> _isFormData = new Collection<bool>();
/// <summary>
/// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data.
/// </summary>
public NameValueCollection FormData
{
get { return _formData; }
}
/// <summary>
/// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation.
/// </summary>
public List<HttpContent> Files
{
get { return _fileContents; }
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
// For form data, Content-Disposition header is a requirement
ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
if (contentDisposition != null)
{
// We will post process this as form data
_isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
return new MemoryStream();
}
// If no Content-Disposition header was present.
throw new InvalidOperationException(string.Format("Did not find required '{0}' header field in MIME multipart body part..", "Content-Disposition"));
}
/// <summary>
/// Read the non-file contents as form data.
/// </summary>
/// <returns></returns>
public override async Task ExecutePostProcessingAsync()
{
// Find instances of non-file HttpContents and read them asynchronously
// to get the string content and then add that as form data
for (int index = 0; index < Contents.Count; index++)
{
if (_isFormData[index])
{
HttpContent formContent = Contents[index];
// Extract name from Content-Disposition header. We know from earlier that the header is present.
ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty;
// Read the contents as string data and add to form data
string formFieldValue = await formContent.ReadAsStringAsync();
FormData.Add(formFieldName, formFieldValue);
}
else
{
_fileContents.Add(Contents[index]);
}
}
}
/// <summary>
/// Remove bounding quotes on a token if present
/// </summary>
/// <param name="token">Token to unquote.</param>
/// <returns>Unquoted token.</returns>
private static string UnquoteToken(string token)
{
if (String.IsNullOrWhiteSpace(token))
{
return token;
}
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
{
return token.Substring(1, token.Length - 2);
}
return token;
}
}
然后,只需使用提供程序获取控制器上的文件即可。
[HttpPost]
public async Task<IHttpActionResult> Post()
{
// get the form data posted and split the content into form data and files
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
// access form data
NameValueCollection formData = provider.FormData;
List<HttpContent> files = provider.Files;
// Do something with files and form data
return Ok();
}