考虑使用ASP.NET Web API编写的Web服务来接受任何数字文件作为“多部分/混合”请求。辅助方法垫如下所示(假设_client
是System.Net.Http.HttpClient
一个实例):如何正确实现一个MediaTypeFormatter来处理'multipart/mixed'类型的请求?
public T Post<T>(string requestUri, T value, params Stream[] streams)
{
var requestMessage = new HttpRequestMessage();
var objectContent = requestMessage.CreateContent(
value,
MediaTypeHeaderValue.Parse("application/json"),
new MediaTypeFormatter[] {new JsonMediaTypeFormatter()},
new FormatterSelector());
var content = new MultipartContent();
content.Add(objectContent);
foreach (var stream in streams)
{
var streamContent = new StreamContent(stream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
streamContent.Headers.ContentDisposition =
new ContentDispositionHeaderValue("form-data")
{
Name = "file",
FileName = "mystream.doc"
};
content.Add(streamContent);
}
return _httpClient.PostAsync(requestUri, content)
.ContinueWith(t => t.Result.Content.ReadAsAsync<T>()).Unwrap().Result;
}
接受在ApiController的子类中的请求的方法,有一个签名如下:
public HttpResponseMessage Post(HttpRequestMessage request)
{
/* parse request using MultipartFormDataStreamProvider */
}
理想情况下,我想这样定义它,根据'Content-Disposition'标题的'name'属性从'multipart/mixed'内容中提取联系人,源和目标。
public HttpResponseMessage Post(Contact contact, Stream source, Stream target)
{
// process contact, source and target
}
然而,我现有的签名,并带有错误消息张贴在InvalidOperationException
数据到服务器的测试结果:
否“MediaTypeFormatter”可阅读 类型的对象“ HttpRequestMessage'与媒体类型'multipart/mixed'。
在互联网上有很多关于如何使用ASP.NET Web API和HttpClient发送和接收文件的例子。但是,我还没有发现任何显示如何处理这个问题。
我开始考虑实施自定义MediaTypeFormatter
并将其注册为全局配置。然而,虽然在自定义MediaTypeFormatter
中处理序列化XML和JSON很容易,但如何处理“多部分/混合”请求并不清楚,这几乎可以成为任何事情。
这似乎工作的伟大与标准格式的数据,但是当有效载荷包含二进制流时,我遇到了一些挑战。我放弃了这个想法,并按照[这里]描述的方式分析了有效载荷(http://www.asp.net/web-api/overview/formats-and-model-binding/html-forms-and-multipart-mime)。该服务在IIS中托管。 – bloudraak 2012-04-11 18:32:39
我提供的解决方案适用于.Net 4.5 Beta。现在,MS正在发布.Net 4.5RC,它还有一种类似但更清晰的方式来处理二进制数据。结帐这篇博文:http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html – Jed 2012-07-18 18:13:32