ASP.NET Core Web API自定义对象JSON序列化格式:实现以schoolName为键的返回结构
实现ASP.NET Core Web API自定义JSON序列化格式
我来给你两种可行的方案,根据你的实际场景选择就行:
方案1:手动转换数据结构(快速适配单个接口)
这种方法不需要修改序列化配置,直接在接口里把原始列表转换成你需要的结构,简单直接,适合只在单个接口需要该格式的场景。
首先要修正你的实体类——原来的字段是私有访问权限,序列化器无法读取,得改成公共属性:
public class SchoolInfo { public string SchoolName { get; set; } public int StudentsCount { get; set; } public int TeachersCount { get; set; } }
然后在API接口里完成结构转换:
[HttpGet] public IActionResult GetSchools() { // 模拟原始数据列表 var originalSchools = new List<SchoolInfo> { new SchoolInfo { SchoolName = "name_1", StudentsCount = 5, TeachersCount = 2 }, new SchoolInfo { SchoolName = "name_2", StudentsCount = 10, TeachersCount = 3 } }; // 转换为目标格式:将每个学校的名称作为键,对应的学生/教师数作为值对象 var formattedResult = originalSchools.ToDictionary( school => school.SchoolName, school => new { school.StudentsCount, school.TeachersCount } ); // 按照你的要求,外层包装成数组返回 return Ok(new List<object> { formattedResult }); }
方案2:自定义JSON转换器(全局/多接口复用)
如果多个接口都需要这种序列化格式,或者想让序列化逻辑和业务代码解耦,可以自定义JSON转换器(默认用System.Text.Json的话)。
步骤1:创建自定义转换器
using System.Text.Json; using System.Text.Json.Serialization; public class SchoolInfoListConverter : JsonConverter<List<SchoolInfo>> { // 如果不需要反序列化该格式,可以暂时抛出异常 public override List<SchoolInfo>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException("反序列化逻辑暂未实现"); } public override void Write(Utf8JsonWriter writer, List<SchoolInfo> value, JsonSerializerOptions options) { // 写入外层数组 writer.WriteStartArray(); // 写入数组内的对象容器 writer.WriteStartObject(); foreach (var school in value) { // 以学校名称为键,写入对应的属性对象 writer.WriteStartObject(school.SchoolName); writer.WriteNumber("studentscount", school.StudentsCount); writer.WriteNumber("teacherscount", school.TeachersCount); writer.WriteEndObject(); } writer.WriteEndObject(); writer.WriteEndArray(); } }
步骤2:注册转换器
全局注册(所有返回List的接口生效)
在Program.cs里配置:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new SchoolInfoListConverter()); });
局部注册(仅特定模型生效)
如果不想全局生效,可以定义一个继承自List
[JsonConverter(typeof(SchoolInfoListConverter))] public class FormattedSchoolList : List<SchoolInfo> { }
然后在接口里返回这个自定义类型:
[HttpGet] public IActionResult GetSchools() { var schoolList = new FormattedSchoolList { new SchoolInfo { SchoolName = "name_1", StudentsCount = 5, TeachersCount = 2 }, new SchoolInfo { SchoolName = "name_2", StudentsCount = 10, TeachersCount = 3 } }; return Ok(schoolList); }
注意事项
- 如果你的项目用的是Newtonsoft.Json(Json.NET)而非默认的System.Text.Json,自定义转换器的逻辑类似,只需继承
Newtonsoft.Json.JsonConverter<List<SchoolInfo>>,并在配置里用AddNewtonsoftJson注册。 - 务必确保实体类的属性是公共的,否则序列化器无法读取字段值。
内容的提问来源于stack exchange,提问作者Hyroglatos_7700
相关产品推荐
相关产品推荐

