如何向ASP.NET Core Web API控制器传递序列化JSON负载?
问题解决:ASP.NET Core Web API接收JSON字符串时400错误
问题根源
你的Generate接口用[FromBody]string reportModel接收参数,ASP.NET Core的JSON绑定器期望请求体是JSON格式的字符串值(即整个内容是被转义后的字符串),而非原始的JSON对象。直接传递{"TemplateName":"myTemplate"}会被JSON解析器识别为对象,无法绑定到string类型,因此返回400错误。
解决方案
1. 修正单元测试的请求内容生成
不要手动拼接字符串,而是用JSON序列化工具将原始JSON字符串转成符合要求的JSON格式字符串,确保内部双引号被正确转义。
用System.Text.Json实现修正:
修改测试方法中的请求内容生成逻辑:
[Fact] public async Task Test1() { var rawJson = "{\"TemplateName\":\"myTemplate\"}"; // 把原始JSON字符串序列化为JSON格式的字符串(自动转义内部引号) var jsonEscapedString = System.Text.Json.JsonSerializer.Serialize(rawJson); using var content = new StringContent(jsonEscapedString, Encoding.UTF8, "application/json"); var server = fixture.Server; var request = server .CreateRequest("/Reporting/generate") .And(req => req.Content = content); var response = await request.PostAsync(); response.EnsureSuccessStatusCode(); }
生成的请求体内容为"{\"TemplateName\":\"myTemplate\"}",符合JSON规范的字符串值,能被ASP.NET Core正确绑定到string reportModel参数。
用Newtonsoft.Json实现(若项目依赖Newtonsoft):
var jsonEscapedString = Newtonsoft.Json.JsonConvert.SerializeObject(rawJson);
2. 控制器代码的可选优化
若无需直接操作原始JSON字符串,建议定义强类型模型接收参数,更简洁且类型安全,避免手动解析JSON的麻烦:
public class ReportModel { public string TemplateName { get; set; } } [HttpPost("generate")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Consumes("application/json")] public async Task<ActionResult> Generate([FromBody] ReportModel reportModel) { try { return Ok(reportModel.TemplateName); } catch (Exception ex) { return BadRequest(ex.Message); } }
这种情况下,单元测试直接传递原始JSON对象即可,无需额外转义:
var rawJson = "{\"TemplateName\":\"myTemplate\"}"; using var content = new StringContent(rawJson, Encoding.UTF8, "application/json");
关于Media Type的说明
application/json的设置完全正确,无论传递的是JSON对象还是JSON格式的字符串,请求体的MIME类型都属于application/json。
内容的提问来源于stack exchange,提问作者clemensoe
相关产品推荐
相关产品推荐

