使用[FromBody]特性实现嵌套模型绑定的方法咨询
解决ASP.NET Core中[FromBody]嵌套模型属性绑定为null的问题
这个问题我之前在项目里也碰到过,结合你描述的场景——预定义类只有带参数构造函数、根模型绑定成功但嵌套属性全为null,核心原因是System.Text.Json(ASP.NET Core默认序列化器)在通过构造函数绑定嵌套类时,参数与JSON属性的匹配逻辑没有正确生效,再加上你的示例里还存在模型与JSON结构不匹配的问题,下面给你分步解决:
一、先修正模型与JSON结构的匹配问题(针对你的示例)
看你的JSON示例:
{ "foo": [ { "bar": { "name": "bar", "firstLetter": "b" } }, { "bar": { "name": "bar1", "firstLetter": "b" } } ] }
但你的Request类定义是:
public class Request{ [JsonConstructor] public Request(Bar b){ this.Bar = b; } public List<Bar> Bar { get; set; } }
这里有两个明显的不匹配:
- JSON里的根属性是
foo,但模型里的属性是Bar,名字对不上; - JSON的
foo是一个数组,每个元素是包含bar对象的结构,而模型直接用List<Bar>,层级不对。
你需要调整模型结构来对应JSON:
public class Request { // 用JsonPropertyName标注对应JSON的"foo"字段 [JsonPropertyName("foo")] public List<FooEntry> FooEntries { get; set; } } // 对应JSON数组里的每个元素 public class FooEntry { [JsonPropertyName("bar")] public Bar Bar { get; set; } } // Bar类保持你的定义 public class Bar { public Bar(string name, string firstLetter){ this.Name = name; this.FirstLetter = firstLetter; } public string Name { get; set; } public string FirstLetter { get; set; } }
二、解决嵌套类属性为null的核心问题
针对你实际场景中(更复杂的嵌套结构),嵌套类的属性全为null的情况,主要有以下几种解决方案:
1. 确保构造函数参数名与JSON属性名匹配
System.Text.Json默认会通过构造函数参数名来匹配JSON属性(默认区分大小写)。如果你的预定义类构造函数参数名和JSON属性名不一致,就会导致绑定失败。
比如你的ContactInfo类构造函数如果是:
public ContactInfo(string System, string Value) { this.system = System; this.value = Value; }
而JSON里的属性是"system"和"value"(小驼峰),参数名是大驼峰,就会匹配不上。这时候可以:
- 要么修改构造函数参数名(如果类库允许),改成和JSON一致的小驼峰:
string system, string value; - 要么在构造函数参数上添加
[JsonPropertyName]特性,明确指定对应JSON属性:public ContactInfo([JsonPropertyName("system")] string System, [JsonPropertyName("value")] string Value) { this.system = System; this.value = Value; }
2. 为预定义类添加无参构造函数(如果允许修改类库)
如果可以修改类库中的类,添加一个无参构造函数,System.Text.Json会优先通过属性赋值的方式绑定,而不是构造函数,这样只要属性名和JSON匹配就能成功:
public class Bar { // 添加无参构造函数(必须是public,否则序列化器无法访问) public Bar() { } public Bar(string name, string firstLetter) { this.Name = name; this.FirstLetter = firstLetter; } public string Name { get; set; } public string FirstLetter { get; set; } }
3. 全局配置JSON序列化选项,开启不区分大小写匹配
在ASP.NET Core的Program.cs中,全局配置JSON序列化器,开启属性名不区分大小写,这样即使参数名和JSON属性名大小写不一致,也能匹配:
var builder = WebApplication.CreateBuilder(args); // 添加控制器并配置JSON选项 builder.Services.AddControllers() .AddJsonOptions(options => { // 开启属性名不区分大小写匹配 options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; // .NET 5+默认支持构造函数绑定,这里确保开启(默认是开启的) options.JsonSerializerOptions.IncludeFields = false; // 只绑定属性,不绑定字段 }); var app = builder.Build(); // ... 其他中间件配置 app.MapControllers(); app.Run();
三、验证步骤
- 先确认模型结构和JSON完全对应,每个层级的属性名、数组/对象类型都匹配;
- 检查嵌套类的构造函数参数是否和JSON属性名匹配,或添加
[JsonPropertyName]标注; - 测试全局配置的序列化选项是否生效;
- 如果类库允许,添加无参构造函数作为兜底方案。
内容的提问来源于stack exchange,提问作者avenmia
相关产品推荐
相关产品推荐

