MinAPI中MapPost的FromBody属性失效,提交表单报HTTP 415错误
问题分析与解决方案
错误原因:HTTP 415 媒体类型不匹配
你遇到的HTTP 415错误,本质是请求的媒体类型和API端点期望的类型不兼容:
- 普通HTML表单默认提交的
Content-Type是application/x-www-form-urlencoded,数据以键值对形式放在请求体中。 [FromBody]参数绑定默认要求请求的Content-Type为application/json(或其他符合Body格式化器的类型),它会尝试将整个请求体解析为指定的参数类型。
两者媒体类型不匹配,导致服务器返回415错误。移除[FromBody]后,MinAPI会自动从表单提交的键值对数据中尝试绑定参数(虽然你的参数是string类型,实际可能获取不到有效数据,但至少不会触发媒体类型校验错误)。
解决方法
方法1:适配表单提交(推荐)
既然用HTML表单提交,就不要用[FromBody],而是定义实体类接收表单字段,让MinAPI自动完成数据绑定:
- 创建表单对应的实体类:
public class VendorFormData { public string Vendor_Name { get; set; } public string Vendor_Id { get; set; } public string Alpha_Name { get; set; } public string Default_Account { get; set; } public string Default_Department { get; set; } }
- 修改API端点代码:
app.MapPost("/api/vendors/add", (VendorFormData formData) => { // 处理formData中的字段,比如保存到数据库 return "/api/vendors/add/result"; });
MinAPI会自动将表单提交的x-www-form-urlencoded数据绑定到VendorFormData的属性上,无需额外配置。
方法2:改用JSON格式提交(保留[FromBody])
如果一定要用[FromBody]接收数据,需要修改表单提交方式,用JavaScript将表单数据转为JSON后提交:
- 修改HTML表单,添加JavaScript提交逻辑:
<form id="vendorForm" method="post" action="/api/vendors/add"> <input type="text" name="vendor_name" placeholder="Vendor Name" size="45"/><br /><br /> <input type="text" name="vendor_id" placeholder="Vendor#" size="45"/><br /><br /> <input type="text" name="alpha_name" placeholder="Alpha" size="45" /><br /><br /> <input type="text" name="default_account" placeholder="Default Account"/><br /><br /> <input type="text" name="default_department" placeholder="Default Department" size="45"/><br /><br /> <input type="submit" /> </form> <script> document.getElementById('vendorForm').addEventListener('submit', async (e) => { e.preventDefault(); // 阻止默认表单提交 const formData = new FormData(e.target); const jsonData = Object.fromEntries(formData); // 将FormData转为JSON对象 // 用fetch提交JSON数据 const response = await fetch('/api/vendors/add', { method: 'POST', headers: { 'Content-Type': 'application/json' // 指定媒体类型为JSON }, body: JSON.stringify(jsonData) // 将JSON对象转为字符串 }); // 处理响应,比如跳转结果页 if (response.ok) { window.location.href = await response.text(); } }); </script>
- 修改API端点(可选接收实体类或直接接收JSON字符串):
// 推荐:接收实体类,自动解析JSON app.MapPost("/api/vendors/add", ([FromBody] VendorFormData formData) => { return "/api/vendors/add/result"; }); // 或者保持接收字符串: app.MapPost("/api/vendors/add", ([FromBody] string jsonString) => { return "/api/vendors/add/result"; });
补充:MinAPI参数绑定规则
- 无特性的复杂类型:默认从请求体解析,若为
x-www-form-urlencoded格式的表单数据,MinAPI也能自动绑定到实体类属性。 - 无特性的简单类型:优先从路由参数、查询参数、表单字段中查找匹配的键值对。
- [FromBody]:强制从请求体解析,要求请求的
Content-Type与配置的格式化器兼容(默认支持JSON)。
内容的提问来源于stack exchange,提问作者eleethesontai
相关产品推荐
相关产品推荐

