JSON.NET игнорирует свойства в типах, происходящих из System.Exception. Зачем?

Я хочу, чтобы 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();
    }
}

Я попытался добавить атрибуты DataContract и DataMember в нужные места. Они не помогают. Как я могу заставить это работать?

Ответ 1

Поскольку 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));

Ответ 2

Вы также можете добавить и загрузить определенный объект в хранилище 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);
    }
}

Таким образом, свойство MyCustomObject будет включено в сериализацию и десериализацию.