微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – WebApi无法读取分块请求

我正在编写一个用于消费一些数据的Web服务.发送它的第三方正在使用多部分请求,当我在WireShark中查看请求时,它会被分块.

当我尝试通过fiddler作为标准(unchunked)请求运行完全相同的请求时,它工作正常,但是,我似乎无法读取分块请求.

我尝试了两种不同的方法.第一:

public HttpResponseMessage ImportEstimate(HttpRequestMessage request)
{
    var data = request.Content.ReadAsMultipartAsync().Result;
    IEnumerable<HttpContent> parts = data.Contents;

    return request.CreateResponse(HttpStatusCode.OK,parts.Count());
}

这不会返回任何东西.它只是坐着,直到请求超时.

第二种方法是:

public HttpResponseMessage ImportEstimate(HttpRequestMessage request)
{
    IEnumerable<HttpContent> parts = null;
    Task.Factory
        .StartNew(() => parts = Request.Content.ReadAsMultipartAsync().Result.Contents,CancellationToken.None,TaskCreationoptions.LongRunning,// guarantees separate thread
            TaskScheduler.Default)
        .Wait();

    return request.CreateResponse(HttpStatusCode.OK,parts.Count());
}

哪个返回错误

Unexpected end of MIME multipart stream. MIME multipart message is not complete.

在这里错过了什么?

编辑:以下是WireShark的请求

POST /myservice/importestimate HTTP/1.1
Host: devapi.mydomain.com
Content-Type: multipart/related; type="application/xop+xml"; start="<start.xml>"; start-info="text/xml"; boundary="--MIME_boundary"
transfer-encoding: chunked
SOAPAction: "importestimate"
X-Forwarded-For: xxx.xx.xxx.xxx
Connection: close

94

----MIME_boundary
Content-Type: application/xop+xml; type="text/xml; charset=UTF-8"
Content-transfer-encoding: 8bit
Content-Id: <start.xml>


170
<?xml version='1.0' encoding='UTF-8' ?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xop="http://www.w3.org/2004/08/xop/include" ><soap:Body><XDOC><XNET_INFO transactionId="001P92V" ><ATTACHMENTS><ATTACHMENT><xop:Include href="cid:[email protected]" /></ATTACHMENT></ATTACHMENTS></XNET_INFO></XDOC></soap:Body></soap:Envelope>
B3

----MIME_boundary
Content-Type: application/zip
Content-transfer-encoding: binary
Content-disposition: attachment; filename="XDOC.ZIP"
Content-Id: <[email protected]>


5BC
... lots of data here removed for brevity...
15

----MIME_boundary--
0

解决方法

经过大量研究,我发现了问题!

显然我的请求并没有以CRLF结束,.Net必须要求发出请求结束的信号.

我最终阅读了整个请求,添加一个CRLF,并从MemoryStream创建了自己的ReadAsMultipartAsync.这似乎有效.

编辑添加代码

private byte[] ProcessInput(HttpRequestMessage request)
{
    List<HttpContent> parts = new List<HttpContent>();
    byte[] result;
    result = request.Content.ReadAsByteArrayAsync().Result;

    // Stupid chunked requests remove the final CRLF,which makes .Net puke on the request.
    // So add our own CRLF.
    List<byte> crlfTemp = result.ToList();
    crlfTemp.Add(0x0D);
    crlfTemp.Add(0x0A);
    result = crlfTemp.ToArray();

    // Convert stream to MIME
    using (var stream = new MemoryStream(result))
    {
        // note: StreamContent has no Content-Type set by default
        // set a suitable Content-Type for ReadAsMultipartAsync()
        var content = new StreamContent(stream);
        content.Headers.ContentType =
            System.Net.Http.Headers.MediaTypeHeaderValue.Parse(
                "multipart/related; boundary=--MIME_boundary");
        content.Headers.ContentLength = result.Length;
        bool isMPC = content.IsMimeMultipartContent();
        Task.Factory
            .StartNew(() => parts = content.ReadAsMultipartAsync().Result.Contents.ToList(),// guarantees separate thread
                TaskScheduler.Default)
            .Wait();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐