【问题标题】:Parsing/Consuming a MultipartFormDataContent (set by MVC) on the WebApi side在 WebApi 端解析/使用 MultipartFormDataContent(由 MVC 设置)
【发布时间】:2016-05-02 03:24:36
【问题描述】:

我得到了 ByteArrayContent 的工作

/* MVC Method , ByteArrayContent */

        private async Task<HttpResponseMessage> ExecuteProxy(string url)
        {
            using (var client = new HttpClient(HttpClientHandlerFactory.GetWindowsAuthenticationHttpClientHandler()))
            {

                byte[] byte1 = new byte[] { 1, 2, 3 };

                ByteArrayContent byteContent = new ByteArrayContent(byte1);

                this.Request.Method = HttpMethod.Post;
                this.Request.Content = byteContent;

                return await client.SendAsync(this.Request);                    

            }
        }

/* WebApi Delegating Handler , ByteArrayContent */

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var byteArray = request.Content.ReadAsByteArrayAsync().Result;

            if (null != byteArray)
            {
                /* I see the byte of "1,2,3" */
            }
        }

下面的方法不是问题的一部分,但为了完整起见,我将其包括在内。

public static class HttpClientHandlerFactory
{
    public static HttpClientHandler GetWindowsAuthenticationHttpClientHandler()
    {
        HttpClientHandler returnHandler = new HttpClientHandler()
        {
            UseDefaultCredentials = true,
            PreAuthenticate = true
        };

        return returnHandler;
    }
}   

我在“获取”WebApi 方面的 MultipartFormDataContent 时遇到了麻烦。

/* MVC Method , MultipartFormDataContent */

        private async Task<HttpResponseMessage> ExecuteProxy(string url)
        {
            using (var client = new HttpClient(HttpClientHandlerFactory.GetWindowsAuthenticationHttpClientHandler()))
            {

                byte[] byte1 = new byte[] { 1, 2, 3 };
                ByteArrayContent byteContent1 = new ByteArrayContent(byte1);

                StringContent stringContent1 = new StringContent("StringContent1Value");

                byte[] byte2 = new byte[] { 4, 5, 6 };
                ByteArrayContent byteContent2 = new ByteArrayContent(byte2);                

                StringContent stringContent2 = new StringContent("StringContent2Value");

                MultipartFormDataContent multipartContent = new MultipartFormDataContent();
                multipartContent.Add(byteContent1, "MyByteArrayContent1");
                multipartContent.Add(stringContent1);   
                multipartContent.Add(byteContent2, "MyByteArrayContent2");
                multipartContent.Add(stringContent2);   



                this.Request.Method = HttpMethod.Post;
                this.Request.Content = multipartContent;

                return await client.SendAsync(this.Request);                    

            }
        }



        /* WebApi Delegating Handler , MultipartFormDataContent*/

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            /* I have no idea how to change this back into a MultipartFormDataContent .. or however else you parse it */
        }

我在谷歌上搜索并阅读了大约 40 篇关于它的 SOF 帖子。解决方案仍然暗示我。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-web-api


    【解决方案1】:

    所以神奇的方法似乎是 ReadAsMultipartAsync

    这有两个问题。一个小,一个显着。

    1. ReadAsMultipartAsync 是一种扩展方法。 (这是小问题)

      /* System.Net.Http.Formatting.dll */

    using System.Net.Http.Headers;
    

    这就是为什么我最初在智能感知中没有看到这种方法。 (我没有在我的 .cs 中添加引用 .. 或 using 语句)

    1. 方法本身存在问题(在下面的链接中概述)

    Request.Content.ReadAsMultipartAsync never returns

    下面是我想出的允许“按名称”查找的方法。

     /* WebApi Delegating Handler , MultipartFormDataContent*/
    
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
    
            /* see https://stackoverflow.com/questions/15201255/request-content-readasmultipartasync-never-returns */
            IEnumerable<HttpContent> contents = null;
            Task.Factory.StartNew(
                    () =>
                    contents = request.Content.ReadAsMultipartAsync().Result.Contents,
                    CancellationToken.None,
                    TaskCreationOptions.LongRunning, // guarantees separate thread
                    TaskScheduler.Default)
                .Wait();
    
            if (null != contents)
            {
                //// This could be accomplished with LINQ queries, but I've left the for-loops in ... so its easier to see what's going on
                foreach (HttpContent currentHttpContent in contents)
                {
                    if (null != currentHttpContent)
                    {
                        if (null != currentHttpContent.Headers)
                        {
                            HttpContentHeaders cheaders = currentHttpContent.Headers;
    
                            if (null != cheaders)
                            {
                                if (null != cheaders.ContentDisposition)
                                {
                                    System.Net.Http.Headers.ContentDispositionHeaderValue cdhv = cheaders.ContentDisposition;
                                    if (null != cdhv)
                                    {
                                        if (!string.IsNullOrEmpty(cdhv.Name))
                                        {
                                            if (cdhv.Name.Equals("MyByteArrayContent1", StringComparison.OrdinalIgnoreCase))
                                            {
                                                byte[] byteArray = null;
                                                ////currentHttpContent.LoadIntoBufferAsync().Wait();
                                                ////currentHttpContent.ReadAsByteArrayAsync().ContinueWith(t =>
                                                ////{
                                                ////    byteArray = t.Result;
                                                ////});
                                                byteArray = currentHttpContent.ReadAsByteArrayAsync().Result;
                                            }
    
                                            /* you can also check for MyByteArrayContent2, StringContent1Value, StringContent2Value as well, left out for brevity */
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    

    其他链接:

    Request.Content.ReadAsMultipartAsync never returns

    Multipart form POST using ASP.Net Web API

    How to get MultipartFormDataContent in Web.API Post method?

    How do I get the file contents of a MultipartMemoryStreamProvider as a byte array?

    Post byte array to Web API server using HttpClient

    Why is the body of a Web API request read once?

    (下面的没有答案)

    How to parse MultipartFormDataContent

    追加:

    这是我发现的 linq 查询:

            if (null != contents)
            {
                /* sometimes the ContentDisposition.Name is null so the extra where filters are helpful to avoid object-null-reference exception */
                HttpContent foundContent = (from cnt in contents
                                           where null!= cnt && null != cnt.Headers && null != cnt.Headers.ContentDisposition && !string.IsNullOrEmpty(cnt.Headers.ContentDisposition.Name) && cnt.Headers.ContentDisposition.Name.Equals("MyByteArrayContent1", StringComparison.OrdinalIgnoreCase)
                                           select cnt).FirstOrDefault();
    
                if (null != foundContent )
                {
                    byte[] byteArray = foundContent .ReadAsByteArrayAsync().Result;
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 1970-01-01
      相关资源
      最近更新 更多