ASP.NET Core 中 DTO 的键值集合属性应使用哪种类型?
适用于ASP.NET Core 5动态属性传输的方案推荐
你遇到的Dictionary<string, object>序列化被忽略的核心原因是:ASP.NET Core 5 默认使用 System.Text.Json 作为序列化器,其对object类型值的序列化存在默认限制,当字典值为非基元类型、或运行时才确定具体类型时,就会出现字段被跳过、序列化不完整的问题。
以下是几种适配性更高的类型选择,按优先级排序:
- 优先选择:
Dictionary<string, JsonElement>
这是 System.Text.Json 原生支持的类型,可兼容所有JSON数据格式(字符串、数字、布尔值、数组、嵌套对象、null),运行期你可以把动态获取的属性值转为JsonElement存入字典,序列化时不会被跳过,前端接收到的就是标准的键值对结构,无需额外适配。不需要修改全局序列化配置,只需替换DTO中对应属性的类型即可。 - 次选:
ExpandoObject
该类型实现了IDictionary<string, object>接口,你可以像操作普通字典一样动态增删属性,System.Text.Json 5及以上版本原生支持ExpandoObject序列化。如果你需要动态属性和DTO的固定属性平级返回给前端,直接让DTO继承ExpandoObject即可,前端接收到的是平铺的JSON对象,使用更方便。 - 兼容现有代码的选择:切换序列化器为Newtonsoft.Json
如果你不想修改现有DTO的Dictionary<string, object>声明,可以改用Newtonsoft.Json作为序列化器,其对该类型的序列化兼容性更好,默认不会跳过字段。配置代码如下:
该方案需要先安装// Startup.cs ConfigureServices方法中添加 services.AddControllers() .AddNewtonsoftJson();Microsoft.AspNetCore.Mvc.NewtonsoftJsonNuGet包。
最佳实践
如果动态属性单独用一个字段存储、不需要和固定属性平级,优先选择Dictionary<string, JsonElement>,性能和兼容性平衡最优;需要平级返回的场景选择ExpandoObject更合适。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

