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

自定义ASP.NET ControllerBase序列化行为 仅序列化接口声明属性

问题原因

ASP.NET Core 默认的 System.Text.Json 序列化器会基于对象的运行时实际类型探查可序列化属性,不会受 Action 声明的返回值接口类型约束,所以 DBProject 类型的所有公开属性都会被序列化输出,而非仅保留 IProject 接口定义的字段。

以下方案均满足「无需提前做对象拷贝转换、无需给实体属性加序列化忽略特性」的要求:

方案1:.NET 7+ 全局配置序列化类型过滤(推荐)

通过修改默认 JSON 序列化的类型信息解析器,全局指定所有 IProject 类型的序列化仅保留接口定义的属性,无需修改业务代码。
在 Program.cs 中添加如下配置:

builder.Services.AddControllers()
    .AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    // 仅处理IProject类型的序列化规则
                    if (typeInfo.Type != typeof(IProject)) return;
                    // 保留IProject接口声明的所有属性
                    var allowedProperties = typeof(IProject)
                        .GetProperties()
                        .Select(p => p.Name)
                        .ToHashSet();
                    // 移除所有接口未定义的属性
                    typeInfo.Properties.RemoveAll(p => !allowedProperties.Contains(p.Name));
                }
            }
        };
    });

配置完成后所有返回 IProject/IEnumerable<IProject> 的接口都会自动按接口定义输出字段,同时兼容 MockProject 和 DBProject 两种实现。

方案2:兼容所有.NET版本 自定义JsonConverter

如果你的项目是 .NET 6 及更早版本,可以通过自定义 IProject 专属的 JSON 转换器实现需求:

  1. 首先实现转换器类:
public class IProjectJsonConverter : JsonConverter<IProject>
{
    public override IProject? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 不需要反序列化可直接抛出异常
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, IProject value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        // 仅序列化IProject定义的属性,后续新增接口字段在此处补充即可
        writer.WriteString(nameof(IProject.Title), value.Title);
        writer.WriteEndObject();
    }
}
  1. 在 Program.cs 中注册转换器:
builder.Services.AddControllers()
    .AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.Converters.Add(new IProjectJsonConverter());
    });

单Action临时适配方案

如果你只需要当前 GetProjects 接口做字段过滤,不需要全局生效,可以直接在Action中指定序列化规则,无需修改全局配置:

[HttpGet]
public ActionResult GetProjects()
{
    IEnumerable<IProject> projects = ...;// 原有获取数据逻辑不变
    return Json(projects, new JsonSerializerOptions
    {
        TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                ti =>
                {
                    if (ti.Type == typeof(IProject))
                    {
                        var allowedProps = typeof(IProject).GetProperties().Select(p => p.Name).ToHashSet();
                        ti.Properties.RemoveAll(p => !allowedProps.Contains(p.Name));
                    }
                }
            }
        }
    });
}

内容的提问来源于stack exchange,提问作者Denise Skidmore

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:39:01