gpt4 book ai didi

c#-4.0 - 如何正确实现 MediaTypeFormatter 来处理 'multipart/mixed' 类型的请求?

转载 作者:行者123 更新时间:2023-12-02 12:08:58 24 4
gpt4 key购买 nike

考虑使用 ASP.NET Web API 编写的 Web 服务来接受任意数量的文件作为“多部分/混合”请求。辅助方法如下所示(假设 _clientSystem.Net.Http.HttpClient 的实例):

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” header 的“name”属性从“multipart/mixed”内容中提取联系人、源和目标。

public HttpResponseMessage Post(Contact contact, Stream source, Stream target)
{
// process contact, source and target
}

但是,使用我现有的签名,将数据发布到服务器会导致 InvalidOperationException 并显示以下错误消息:

No 'MediaTypeFormatter' is available to read an object of type 'HttpRequestMessage' with the media type 'multipart/mixed'.

互联网上有许多如何使用 ASP.NET Web API 和 HttpClient 发送和接收文件的示例。但是,我还没有找到任何说明如何处理此问题的方法。

我开始考虑实现自定义 MediaTypeFormatter 并将其注册到全局配置中。然而,虽然在自定义 MediaTypeFormatter 中处理序列化 XML 和 JSON 很容易,但尚不清楚如何处理几乎可以是任何内容的“多部分/混合”请求。

最佳答案

看看这个论坛:http://forums.asp.net/t/1777847.aspx/1?MVC4+Beta+Web+API+and+multipart+form+data

下面是一段代码(由 imran_ku07 发布),可以帮助您实现自定义格式化程序来处理多部分/表单数据:

public class MultiFormDataMediaTypeFormatter : FormUrlEncodedMediaTypeFormatter
{
public MultiFormDataMediaTypeFormatter() : base()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}

protected override bool CanReadType(Type type)
{
return true;
}

protected override bool CanWriteType(Type type)
{
return false;
}

protected override Task<object> OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext)
{
var contents = formatterContext.Request.Content.ReadAsMultipartAsync().Result;
return Task.Factory.StartNew<object>(() =>
{
return new MultiFormKeyValueModel(contents);
});
}

class MultiFormKeyValueModel : IKeyValueModel
{
IEnumerable<HttpContent> _contents;
public MultiFormKeyValueModel(IEnumerable<HttpContent> contents)
{
_contents = contents;
}


public IEnumerable<string> Keys
{
get
{
return _contents.Cast<string>();
}
}

public bool TryGetValue(string key, out object value)
{
value = _contents.FirstDispositionNameOrDefault(key).ReadAsStringAsync().Result;
return true;
}
}
}

然后您需要将此格式化程序添加到您的应用程序中。如果进行自托管,您只需添加以下内容即可:

config.Formatters.Insert(0, new MultiFormDataMediaTypeFormatter());

在实例化 HttpSelfHostServer 类之前。

--编辑--

要解析二进制流,您需要另一个格式化程序。这是我在我的一个工作项目中用来解析图像的一个。

class JpegFormatter : MediaTypeFormatter
{
protected override bool CanReadType(Type type)
{
return (type == typeof(Binary));
}

protected override bool CanWriteType(Type type)
{
return false;
}

public JpegFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpeg"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpg"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/png"));
}

protected override Task<object> OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext)
{
return Task.Factory.StartNew(() =>
{
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, (int)fileBytes.Length);

return (object)new Binary(fileBytes);
});
}

protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, TransportContext transportContext)
{
throw new NotImplementedException();
}
}

在您的 Controller /操作中,您需要执行以下操作:

public HttpResponseMessage UploadImage(Binary File) {
//do something with your file
}

关于c#-4.0 - 如何正确实现 MediaTypeFormatter 来处理 'multipart/mixed' 类型的请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10036445/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com