使用 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;
}
我有一个小应用程序可以生成包含多部分内容的 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;
}