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

无法将继承DynamicObject的类序列化为JSON字符串

解决DynamicObject子类序列化后得到空白对象的问题

我完全懂你遇到的这个困扰——当你的Foo类继承自DynamicObject后,Newtonsoft.Json默认的序列化逻辑会“走偏”,它会优先通过DynamicObject的动态成员访问方法(比如TryGetMember)来处理对象,而不会自动反射并序列化你定义的Properties字典,所以最终才会输出空对象{}。

下面给你几个实用的解决方案:

方案一:自定义JsonConverter(最推荐)

写一个专门针对Foo类的转换器,直接控制序列化/反序列化的逻辑,把Properties字典的内容输出:

public class FooConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Foo);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var foo = new Foo();
        var props = serializer.Deserialize<Dictionary<string, object>>(reader);
        foreach (var kvp in props)
        {
            foo.Properties[kvp.Key] = kvp.Value;
        }
        return foo;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var foo = value as Foo;
        serializer.Serialize(writer, foo.Properties);
    }
}

使用方式有两种:

  1. 序列化时手动指定转换器:
var foo = new Foo();
foo.Properties["UserName"] = "Pranay Deep";
var json = JsonConvert.SerializeObject(foo, new FooConverter());
  1. 给Foo类添加特性,自动应用转换器:
[JsonConverter(typeof(FooConverter))]
public class Foo : DynamicObject
{
    public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();
    // 其他代码...
}

方案二:实现ISerializable接口

通过实现ISerializable接口,手动定义序列化和反序列化的规则:

[Serializable]
public class Foo : DynamicObject, ISerializable
{
    public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // 把Properties里的键值对加入序列化信息
        foreach (var kvp in Properties)
        {
            info.AddValue(kvp.Key, kvp.Value);
        }
    }

    // 反序列化需要的构造函数
    protected Foo(SerializationInfo info, StreamingContext context)
    {
        Properties = new Dictionary<string, object>();
        foreach (var entry in info)
        {
            Properties[entry.Name] = entry.Value;
        }
    }
}

这样Json.NET会严格按照你定义的逻辑处理对象,把Properties的内容完整序列化。

方案三:用JsonObject特性强制序列化公共成员

给Foo类加上[JsonObject(MemberSerialization.OptOut)]特性,告诉Json.NET序列化所有静态定义的公共成员(包括你的Properties字典):

[JsonObject(MemberSerialization.OptOut)]
public class Foo : DynamicObject
{
    public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();
    // 其他代码...
}

这个方案最简单,但要注意:它只会处理类里静态定义的公共属性,如果你通过DynamicObject动态添加的成员,还是不会被序列化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:19:38