API 控制器 POST 方法 multipart/form-data 使用边界获取主体内的消息
API controller POST method multipart/form-data using boundary get message inside the body
我在可以管理具有 'multipart/form-data; boundary=boundary'
请求的 API 控制器上开发 C# (.Net 5) 方法时遇到问题
我无法在客户端更改请求,我只能修改我的后端以适应它。
请求指定了 'Content-Type: multipart/form-data; boundary=boundary',正文中有一条 json 消息需要提取。
请求正文中的消息如下所示:
--boundary
Content-Disposition: form-data; name="ZZZZZZZZZZ"
Content-Type: application/json
Content-Length: 474
{
//a well formed json
}
--boundary--
我可以使用以下代码得到它:string dataMessage = new StreamReader(Request.Body).ReadToEndAsync().Result;
然后我可以使用 IndexOf 和 Substring 手动解析该字符串以仅提取 json 部分,然后使用 JsonConvert 将其转换为对象。
我想知道 .Net 上是否有一些选项可以自动执行此操作而无需手动解析字符串。我认为一定有某种方法可以解释边界令牌并直接获取 json 数据。但我找不到任何 :( 我想到了这一点,因为当使用 webhook.site 测试客户端请求时,它可以毫无问题地解析消息。
我的控制器定义是这样的
[ApiController]
[Route("api/[controller]")]
public class XXXXController : ControllerBase
方法是这样的
[HttpPost]
[Route("[action]")]
public IActionResult YYYYYYY()
我已经尝试指定模型绑定来更改行为,但我无法让它工作。
而且我在提问之前已经搜索了帮助:
- https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0#model-binding-for-http-get-requests
- https://forums.asp.net/t/2162362.aspx?Read+POST+data+in+request+body
- How to get POST data in WebAPI?
- how to read multi part form data in .net web api controller
- ASP.NET MVC. How to create Action method that accepts and multipart/form-data
- 415 Unsupported Media Type when uploading "multipart/form-data" to .Net Core 3.1 API but the file is accessible in middleware method
- Send POST request through WebClient with boundary
- How to get Json Post Values with asp.net webapi
- What is the boundary in multipart/form-data?
感谢您的帮助!!
默认情况下,.Net5 中不支持 multi-part/form-data
媒体类型。因此,输入格式化程序应附加到 MvcBuilder
.
考虑到您无法在客户端进行操作,ApiMultipartFormDataFormatter 可以使用启用此类输入格式的功能。
- 添加包:
Install-Package ApiMultipartFormDataFormatter -Version 3.0.0
在Startup.cs
中配置格式化程序
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.InputFormatters.Add(new MultipartFormDataFormatter());
});
}
假设上述格式正确的 json 如下所示 class:
public class CustomContent
{
public string Name { get; set; }
}
因此,我们需要将其包装到另一个包含此参数的 class 中。
注意: 库目前不支持反序列化因此,getter-only 属性 添加到 returns 反序列化的模型中对象。
public class ViewModel
{
// Equivalent to ZZZZZZZZZZ
public string SerializedContent { get; set; }
public CustomContent Content => !string.IsNullOrEmpty(SerializedContent)
? JsonConvert.DeserializeObject<CustomContent>(SerializedContent)
: null;
}
改造 Action 以接受包装器模型。
[HttpPost]
[Route("[action]")]
public IActionResult Parse(ViewModel vm)
{
return Ok($"Received Name: {vm?.Content?.Name}");
}
对应示例的工作cURL请求为:
curl --location --request POST 'http://localhost:25599/api/MultiPart/Parse'
\
--header 'Content-Type: multipart/form-data; boundary=boundary' \
--data-raw '--boundary
Content-Disposition: form-data; name="SerializedContent"
Content-Type: application/json
Content-Length: 100
{
"Name" : "Foo"
}
--boundary--'
响应应等于 Received Name: Foo
。
我在可以管理具有 'multipart/form-data; boundary=boundary'
请求的 API 控制器上开发 C# (.Net 5) 方法时遇到问题我无法在客户端更改请求,我只能修改我的后端以适应它。
请求指定了 'Content-Type: multipart/form-data; boundary=boundary',正文中有一条 json 消息需要提取。
请求正文中的消息如下所示:
--boundary
Content-Disposition: form-data; name="ZZZZZZZZZZ"
Content-Type: application/json
Content-Length: 474
{
//a well formed json
}
--boundary--
我可以使用以下代码得到它:string dataMessage = new StreamReader(Request.Body).ReadToEndAsync().Result;
然后我可以使用 IndexOf 和 Substring 手动解析该字符串以仅提取 json 部分,然后使用 JsonConvert 将其转换为对象。
我想知道 .Net 上是否有一些选项可以自动执行此操作而无需手动解析字符串。我认为一定有某种方法可以解释边界令牌并直接获取 json 数据。但我找不到任何 :( 我想到了这一点,因为当使用 webhook.site 测试客户端请求时,它可以毫无问题地解析消息。
我的控制器定义是这样的
[ApiController]
[Route("api/[controller]")]
public class XXXXController : ControllerBase
方法是这样的
[HttpPost]
[Route("[action]")]
public IActionResult YYYYYYY()
我已经尝试指定模型绑定来更改行为,但我无法让它工作。
而且我在提问之前已经搜索了帮助:
- https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0#model-binding-for-http-get-requests
- https://forums.asp.net/t/2162362.aspx?Read+POST+data+in+request+body
- How to get POST data in WebAPI?
- how to read multi part form data in .net web api controller
- ASP.NET MVC. How to create Action method that accepts and multipart/form-data
- 415 Unsupported Media Type when uploading "multipart/form-data" to .Net Core 3.1 API but the file is accessible in middleware method
- Send POST request through WebClient with boundary
- How to get Json Post Values with asp.net webapi
- What is the boundary in multipart/form-data?
感谢您的帮助!!
默认情况下,.Net5 中不支持 multi-part/form-data
媒体类型。因此,输入格式化程序应附加到 MvcBuilder
.
考虑到您无法在客户端进行操作,ApiMultipartFormDataFormatter 可以使用启用此类输入格式的功能。
- 添加包:
Install-Package ApiMultipartFormDataFormatter -Version 3.0.0
在
中配置格式化程序Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { options.InputFormatters.Add(new MultipartFormDataFormatter()); }); }
假设上述格式正确的 json 如下所示 class:
public class CustomContent { public string Name { get; set; } }
因此,我们需要将其包装到另一个包含此参数的 class 中。 注意: 库目前不支持反序列化因此,getter-only 属性 添加到 returns 反序列化的模型中对象。
public class ViewModel { // Equivalent to ZZZZZZZZZZ public string SerializedContent { get; set; } public CustomContent Content => !string.IsNullOrEmpty(SerializedContent) ? JsonConvert.DeserializeObject<CustomContent>(SerializedContent) : null; }
改造 Action 以接受包装器模型。
[HttpPost] [Route("[action]")] public IActionResult Parse(ViewModel vm) { return Ok($"Received Name: {vm?.Content?.Name}"); }
对应示例的工作cURL请求为:
curl --location --request POST 'http://localhost:25599/api/MultiPart/Parse'
\
--header 'Content-Type: multipart/form-data; boundary=boundary' \
--data-raw '--boundary
Content-Disposition: form-data; name="SerializedContent"
Content-Type: application/json
Content-Length: 100
{
"Name" : "Foo"
}
--boundary--'
响应应等于 Received Name: Foo
。