JSON.NET忽略从System.Exception派生的类型中的属性.为什么?

wwa*_*rby 15 c# serialization json json.net

我想JSON序列化一个继承System.Exception的自定义异常对象.JsonConvert.SerializeObject似乎忽略派生类型的属性.问题可以很简单地说明:

class MyException : Exception {
    public string MyProperty { get; set; }
}

class Program {
    static void Main(string[] args) {
        Console.WriteLine(JsonConvert.SerializeObject(new MyException {MyProperty = "foobar"}, Formatting.Indented));
        //MyProperty is absent from the output. Why?
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试在正确的位置添加DataContract和DataMember属性.他们没有帮助.我如何让它工作?

Mik*_*ray 16

因为Exception实现ISerializable,Json.Net默认使用它来序列化对象.您可以这样忽略它ISerializable:

var settings = new JsonSerializerSettings() {
    Formatting = Formatting.Indented,
    ContractResolver = new DefaultContractResolver() { 
        IgnoreSerializableInterface = true 
    } 
};
Console.WriteLine(JsonConvert.SerializeObject(new MyException {MyProperty = "foobar"}, settings));
Run Code Online (Sandbox Code Playgroud)

  • 这将导致错误,因为异常具有自引用成员.除了代码之外,你还必须在`JsonSerializerSettings`中指定`ReferenceLoopHandling = ReferenceLoopHandling.Ignore`.无论如何,我认为以这种方式序列化异常是一个非常糟糕的主意,因为`TargetSite`属性可以生成一个非常重的字符串(如几MBytes). (3认同)

Tho*_*ena 8

您还可以System.Runtime.Serialization.SerializationInfo通过重写GetObjectData方法和以下方法将特定对象添加和检索到商店中ctor(SerializationInfo, StreamingContext):

public class MyCustomException : Exception
{
    public string MyCustomData { get; set; }

    protected MyCustomException (SerializationInfo info, StreamingContext context) : base(info, context)
    {
        MyCustomData = info.GetString("MyCustomData");
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);
        info.AddValue("MyCustomData", MyCustomData);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,该MyCustomObject属性将包含在序列化和反序列化中.

  • 除此之外,我需要将`[Serializable]`属性添加到派生的异常类中,以使其工作 (3认同)