使用AutoMapper时如何让DTO的JsonProperty自定义字段名生效?
JsonProperty特性不生效 你碰到的[JsonProperty]打了没反应的核心原因非常直接:.NET Core 3.0之后新建的Web API项目,默认的JSON序列化引擎已经不再使用Newtonsoft.Json,换成了.NET内置的System.Text.Json。
你在DTO上写的[JsonProperty]是Newtonsoft.Json专属的特性,System.Text.Json根本不识别这个标签的规则,自然不会按你定义的自定义字段名输出,最后就按照System.Text.Json默认的小驼峰规则转换字段名,输出了你现在看到的默认格式。
另外要明确:这个问题和AutoMapper完全没有关系。AutoMapper的职责只是把StudentEntity的属性值拷贝到StudentModel的对应属性上,你之前能看到正确的属性值就说明映射逻辑是通顺的,后续把对象转成JSON字符串输出是ASP.NET Core HTTP管道的工作,不在AutoMapper的负责范围内。
方案一:继续使用Newtonsoft.Json做序列化(改动最小,原有DTO代码不用改)
如果项目本身对Newtonsoft.Json有依赖,不想换序列化引擎,只要两步就能解决问题:
- 安装对应版本的NuGet包:.NET 5及以上直接安装
Microsoft.AspNetCore.Mvc.NewtonsoftJson,.NET Core 3.x安装版本兼容的同包即可。 - 在项目的服务注册位置(.NET 6+的Program.cs、老版本的Startup.cs)把控制器的序列化配置切换到Newtonsoft:
.NET 6+ minimal Hosting写法示例:
builder.Services.AddControllers() .AddNewtonsoftJson();
老版本Startup写法示例:
public void ConfigureServices(IServiceCollection services) { services.AddControllers() .AddNewtonsoftJson(); }
配置完成后,序列化管道就能正确识别你DTO上写的Newtonsoft版[JsonProperty]特性,直接输出你期望的自定义字段名,不需要修改其他业务代码。
方案二:使用内置System.Text.Json序列化,不引入Newtonsoft.Json依赖
如果不想额外增加Newtonsoft.Json的包依赖,那就把DTO上错用的Newtonsoft特性替换成System.Text.Json提供的同功能特性[JsonPropertyName],该特性的命名空间为System.Text.Json.Serialization,修改后的DTO代码如下:
using System.Text.Json.Serialization; public class StudentModel { [JsonPropertyName("Admission Number")] public string StudentId { get; set; } [JsonPropertyName("Date of Birth")] public string DOB { get; set; } [JsonPropertyName("Name")] public string StudentName { get; set; } }
修改完成后直接运行即可,同样不需要调整AutoMapper的映射配置。
- 两个JSON库的特性不能混用:Newtonsoft的自定义字段标签是
[JsonProperty],System.Text.Json的对应标签是[JsonPropertyName],哪个引擎负责序列化就用哪个库的标签,错用了肯定无法生效。 - 你现在接口返回的小驼峰格式(
studentId、dOB这类命名),正好是System.Text.Json的默认命名规则,也能反过来确认当前项目确实没有启用Newtonsoft序列化。 - 不需要调整AutoMapper的映射配置,实体到DTO的映射逻辑本身没有问题,问题从头到尾都出在序列化环节,和映射层无关。
内容的提问来源于stack exchange,提问作者11738472

