使用 MultipartContent - 它正在工作,但它工作正常吗?

Using MultipartContent - It's working, but is it working right?

我有一个小应用程序可以生成包含多部分内容的 HttpMessage ...

using (var client = new HttpClient())
{
    using (var content = new MultipartContent("mixed", "----123"))
    {
        content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/mixed; boundary=----123");
        // repeated calls to content.Add(...)

        var result = client.PostAsync(url, content). Result;

        Console.WriteLine(result);
    }
}

我有一个小的 HttpServer 可以侦听 POST 调用并在收到调用时执行此操作...

var streamContent = new StreamContent(inputStream);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/mixed; boundary=----123");
var provider = streamContent.ReadAsMultipartAsync().Result;

foreach (var httpContent in provider.Contents)
{
    var t = httpContent.Headers.ContentType;
    var c = httpContent.ReadAsStringAsync().Result;
}

一切正常。

但是,如果在我的接收器代码中,我包含行streamContent.Headers.ContentType...,接收器会在var provider...行崩溃并出现错误Invalid 'HttpContent' instance provided. It does not have a content-type header value. 'HttpContent' instances must have a content-type header starting with 'multipart/'..

所以,虽然我有可用的代码,但只有在我事先知道边界是什么的情况下,它才会起作用。

这不可能是对的。

我已经查看并尝试了数十种基于 SO 和其他地方问题的排列,但是如果没有我在 ContentType header接收器,因此知道边界值是多少。

应该做什么?

更新

如果我删除接收器中 ContentType header 的边界部分,它仍然会崩溃,但会出现不同的错误...Invalid 'HttpContent' instance provided. It does not have a 'multipart' content-type header with a 'boundary' parameter.

我认为您的服务器并没有像您认为的那样工作。 new StreamContent(Stream) 在您创建自己的流内容并打算从控制器操作中 return 时使用。您传递给它的流应该包含将被 returned 的原始数据(实体、响应 body)。它不会尝试以任何方式解释流中的数据。即使您在参数中传递有效的 http 流,它也不会尝试从中解析 content-type headers - 您必须提供它。这是一个很大的 IF,你没有显示你从哪里得到 inputStream,它不是 MVC 的标准部分。

您从客户端收到的实际内容可在 Request.Content 中访问,连同适当的 headers,如 content-type 或边界。 ReadAsMultipartAsync 也应该适用于此,但我从未在实践中尝试过该扩展。

作为旁注,使用 Task.Result 应该是最后的手段。使您的控制器操作异步并等待该任务。

编辑:为了说明,我认为这可行并且不需要提前知道边界。尽管如此,当您可以调用 Request.Content.ReadAsMultipartAsync():

时,它仍然是非常次优的解决方案
var streamContent = new StreamContent(inputStream);
streamContent.Headers.ContentType = Request.Content.Headers.ContentType;
                                 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var provider = streamContent.ReadAsMultipartAsync().Result;

foreach (var httpContent in provider.Contents)
{
    var t = httpContent.Headers.ContentType;
    var c = httpContent.ReadAsStringAsync().Result;
}