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

如何用Json.NET按接口定义序列化对象,支持非原始类型属性

C# 基于接口限定JSON序列化属性范围(支持嵌套非原始类型)

需求背景

需要基于接口定义完成对象的JSON序列化,仅保留接口内声明的所有属性,忽略实现类的自有属性,同时支持接口定义的复杂类型、嵌套对象的完整序列化。

示例代码定义

public interface IInterface
{
    SubClass Sub { get; set; }
    int A { get; set; }
}

public class Class : IInterface
{
    public SubClass Sub { get; set; } = new();
    public int A { get; set; } = 1;
    public int B { get; set; } = 1;
}

public class SubClass
{
    public int C { get; set; } = 2;
}

期望序列化效果

对Class类的实例序列化时,输出内容如下,仅保留IInterface定义的Sub、A属性,忽略类自有属性B,同时嵌套的Sub属性完整序列化:

{"Sub":{"C":2},"A":1}

实现方案

通过自定义DefaultContractResolver实现属性筛选,代码如下:

public class InterfaceContractResolver : DefaultContractResolver
{
    private readonly Type[] _interfaceTypes;
    private readonly ConcurrentDictionary<Type, Type> _typeToSerializeMap;

    public InterfaceContractResolver(params Type[] interfaceTypes)
    {
        _interfaceTypes = interfaceTypes;
        _typeToSerializeMap = new ConcurrentDictionary<Type, Type>();
    }

    protected override IList<JsonProperty> CreateProperties(
        Type type,
        MemberSerialization memberSerialization)
    {
        var typeToSerialize = _typeToSerializeMap.GetOrAdd(
            type,
            t => _interfaceTypes.FirstOrDefault(
                it => it.IsAssignableFrom(t)) ?? t);

        var props = base.CreateProperties(typeToSerialize, memberSerialization);

        // 标记所有属性为不忽略
        foreach (var prop in props)
        {
            prop.Ignored = false;
        }

        return props;
    }
}

使用方式

序列化时在JsonSerializerSettings中指定自定义的ContractResolver,传入要作为序列化范围限定的接口类型即可:

var target = new Class();
string jsonResult = JsonConvert.SerializeObject(target, new JsonSerializerSettings
{
    ContractResolver = new InterfaceContractResolver(typeof(IInterface))
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:30:00