无法将继承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); } }
使用方式有两种:
- 序列化时手动指定转换器:
var foo = new Foo(); foo.Properties["UserName"] = "Pranay Deep"; var json = JsonConvert.SerializeObject(foo, new FooConverter());
- 给
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
相关产品推荐
相关产品推荐

