Controller解析输入异常:提交JSON参数为何持续报错?
ASP.NET Core接口400错误排查
问题代码与请求信息
Controller方法
public async Task<ActionResult> SubmitFormAsync([FromBody] Dictionary<string, string> input, Guid formGuid)
Postman提交的JSON
{ "input": { "firstname": "Toren", "jobtitle": "Activist", "lastname": "SO", "message": "", "phone": "+123455667" } }
收到的400错误响应
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-79f401cda7f4cdb640dbd8c95dc851d5-a6b4228c3e1675ba-00", "errors": { "input": [ "The input field is required." ], "$.input": [ "The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.String,System.String]. Path: $.input | LineNumber: 1 | BytePositionInLine: 12." ] } }
错误原因分析
两个核心问题导致400错误:
- 参数绑定不匹配:
[FromBody]修饰的input参数期望直接接收Dictionary<string, string>类型的JSON,但你提交的JSON是一个包含input键的外层对象,框架无法将这个外层对象转换为Dictionary,因此抛出转换错误。 formGuid参数未传递:方法中的formGuid是独立参数,默认会从路由或查询参数中获取,但你没有在请求中传递这个参数,因此触发必填校验错误。
解决方案
方案一:调整请求格式(推荐)
直接匹配[FromBody]的绑定规则,同时正确传递formGuid:
- 修改请求Body:去掉外层的
input键,直接传递Dictionary对应的JSON:
{ "firstname": "Toren", "jobtitle": "Activist", "lastname": "SO", "message": "", "phone": "+123455667" }
- 传递
formGuid:将formGuid通过以下两种方式之一传递:- 路由参数:修改接口路由定义为
[HttpPost("SubmitForm/{formGuid}")],请求URL设为https://your-api-url/SubmitForm/你的GUID值 - 查询参数:请求URL设为
https://your-api-url/SubmitForm?formGuid=你的GUID值
- 路由参数:修改接口路由定义为
方案二:创建DTO适配现有请求格式
如果不想修改请求结构,可以定义一个DTO类来接收外层对象:
public class FormSubmitRequest { public Dictionary<string, string> Input { get; set; } }
然后修改Controller方法:
public async Task<ActionResult> SubmitFormAsync([FromBody] FormSubmitRequest request, Guid formGuid)
此时框架会自动将Body中的input键值对绑定到request.Input,同时formGuid仍需通过路由或查询参数传递。
内容的提问来源于stack exchange,提问作者I am not Fat
相关产品推荐
相关产品推荐

