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

Newtonsoft.Json转System.Text.Json:接口序列化结果不一致的解决方法

问题:System.Text.Json序列化接口类型对象与Newtonsoft.Json行为差异

当使用System.Text.Json序列化接口类型的对象时,结果为空对象{},但使用Newtonsoft.Json却能正确序列化出实现类的属性。以下是具体代码示例:

接口与实现类定义

public interface ITestClass
{
}

public class TestClass : ITestClass
{
    public int MyProperty { get; set; }
}

Newtonsoft.Json序列化效果

var testClass = new TestClass { MyProperty = 5 };
var result1 = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(testClass));
var result2 = Encoding.UTF8.GetString(result1); // 输出:{"MyProperty":5}

System.Text.Json序列化效果

var testClass = new TestClass { MyProperty = 5 };
var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass);
var result2 = Encoding.UTF8.GetString(result1); // 输出:{}
解决方案

System.Text.Json默认仅序列化变量编译时类型的成员,当变量声明为接口类型时,不会自动序列化实现类的额外属性。要实现和Newtonsoft.Json一致的效果,可采用以下几种方法:

  • 指定序列化的实际类型
    调用Serialize方法时,明确传入对象的实际类型:

    var testClass = new TestClass { MyProperty = 5 };
    // 方法1:通过GetType()获取实际类型
    var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass, testClass.GetType());
    // 方法2:显式指定实现类类型
    var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass, typeof(TestClass));
    
  • 配置多态序列化支持
    让System.Text.Json识别接口的派生类型,有两种配置方式:
    方式一:给接口添加特性标记

    [JsonDerivedType(typeof(TestClass))]
    public interface ITestClass
    {
    }
    
    // 序列化时使用默认配置即可
    var testClass = new TestClass { MyProperty = 5 };
    var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass);
    

    方式二:在序列化配置中手动添加派生类型

    var options = new JsonSerializerOptions();
    options.TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { typeInfo =>
            {
                if (typeInfo.Type == typeof(ITestClass))
                {
                    typeInfo.PolymorphismOptions.DerivedTypes.Add(new JsonDerivedType(typeof(TestClass)));
                }
            }
        }
    };
    
    var testClass = new TestClass { MyProperty = 5 };
    var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass, typeof(ITestClass), options);
    
  • 自定义JsonConverter处理
    编写自定义转换器,序列化时以对象的实际类型进行处理:

    public class InterfaceConverter<TInterface> : JsonConverter<TInterface>
    {
        public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 若需要反序列化功能,可在此实现逻辑
            throw new NotImplementedException();
        }
    
        public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options)
        {
            // 按对象实际类型序列化
            JsonSerializer.Serialize(writer, value, value.GetType(), options);
        }
    }
    
    // 使用时添加转换器到配置
    var options = new JsonSerializerOptions();
    options.Converters.Add(new InterfaceConverter<ITestClass>());
    
    var testClass = new TestClass { MyProperty = 5 };
    var result1 = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(testClass, options);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:55:33