You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:52:32