一个人如何正确地实施MediaTypeFormatter处理类型的请求“的multipart /混合”? [英] How does one correctly implement a MediaTypeFormatter to handle requests of type 'multipart/mixed'?

查看:1601
本文介绍了一个人如何正确地实施MediaTypeFormatter处理类型的请求“的multipart /混合”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑写的ASP.NET Web API Web服务来接受任何数量的文件作为一个多部分/混合的要求。辅助方法垫如下所示(假设 _client 是一个实例 System.Net.Http.HttpClient

Consider a web service written in ASP.NET Web API to accept any number files as a 'multipart/mixed' request. The helper method mat look as follows (assuming _client is an instance of System.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的子类中的请求的方法,有一个签名如下:

The method that accepts the request in the subclass of ApiController has a signature as follows:

public HttpResponseMessage Post(HttpRequestMessage request)
{
    /* parse request using MultipartFormDataStreamProvider */
}

在理想情况下,我想定义它像这样,在那里接触,源和目标是从基于内容处置标头的名称属性中的多部分/混合内容中提取。

Ideally, I'd like to define it like this, where contact, source and target are extracted from the 'multipart/mixed' content based on the 'name' property of the 'Content-Disposition' header.

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

不过,我现有的签名,用一个错误信息张贴数据到服务器导致一个出现InvalidOperationException

没有'MediaTypeFormatter可阅读类型的对象
  Htt的prequestMessage与媒体类型多部分/混合。

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

有一些在互联网上的例子如何使用ASP.NET Web API和HttpClient的发送和接收文件。但是,我还没有发现任何显示如何处理这个问题。

There are a number of examples on the internet how to send and receive files using the ASP.NET Web API and HttpClient. However, I have not found any that show how to deal with this problem.

我开始考虑实现自定义的 MediaTypeFormatter 和全局配置注册。然而,尽管它很容易对付的自定义 MediaTypeFormatter 序列化XML和JSON,目前还不清楚如何处理它可以pretty'多部分/混合的要求多少是任何东西。

I started looking at implementing a custom MediaTypeFormatter and register it with the global configuration. However, while it is easy to deal with serializing XML and JSON in a custom MediaTypeFormatter, it is unclear how to deal with 'multipart/mixed' requests which can pretty much be anything.

推荐答案

有一个在这个论坛:<一href=\"http://forums.asp.net/t/1777847.aspx/1?MVC4+Beta+Web+API+and+multipart+form+data\">http://forums.asp.net/t/1777847.aspx/1?MVC4+Beta+Web+API+and+multipart+form+data

下面是code(张贴imran_ku07),可以帮助你实现一个自定义格式来处理的multipart / form-data的一个片段:

Here is a snippet of code (posted by imran_ku07) that might help you implement a custom formatter to handle the multipart/form-data:

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;
        }
    }
}

您接着需要此格式添加到您的应用程序。如果做自主机你可以简单地包括添加:

You then need to add this formatter to your application. If doing self-host you can simply add it by including:

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

在实例化HttpSelfHostServer类。

before instantiating the HttpSelfHostServer class.

- 编辑 -

要解析二进制流,你需要另一个格式化。这里有一个,我用我的工作项目之一来解析图像。

To parse binary streams you'll need another formatter. Here is one that I am using to parse images in one of my work projects.

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();
    }
}

在你的控制器/动作,你会想要做的线沿线的东西:

In your controller/action you'll want to do something along the lines of:

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

这篇关于一个人如何正确地实施MediaTypeFormatter处理类型的请求“的multipart /混合”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆