Deserializing custom exceptions in Newtonsoft.Json

前端 未结 1 563
天命终不由人
天命终不由人 2021-01-14 03:37

I\'ve been having trouble deserializing custom exceptions in Newtonsoft.Json version 11.0.2. It works fine in Newtonsoft.Json version 10.0.3.

I serialize and deseria

相关标签:
1条回答
  • 2021-01-14 03:43

    In Json.NET 11 a change was made to how ISerializable types are serialized. According to the release notes:

    • Change - Types that implement ISerializable but don't have [SerializableAttribute] are not serialized using ISerializable

    Thus you must now mark your exception types with SerializableAttribute:

    [Serializable]
    public sealed class MyHttpException : MyBaseException
    {
    }
    
    [Serializable]
    public abstract class MyBaseException : Exception
    {
    }
    

    Alternatively, you could create a custom contract resolver that restores the old behavior:

    public class PreferISerializableContractResolver : DefaultContractResolver
    {
        protected override JsonContract CreateContract(Type objectType)
        {
            var contract = base.CreateContract(objectType);
    
            if (!IgnoreSerializableInterface
                && contract is JsonObjectContract
                && typeof(ISerializable).IsAssignableFrom(objectType)
                && !objectType.GetCustomAttributes(true).OfType<JsonContainerAttribute>().Any())
            {
                contract = CreateISerializableContract(objectType);
            }
    
            return contract;
        }
    }
    

    (You may want to cache the contract resolver for best performance.)

    Why was this change made? According to Issue #1622: classes deriving from System.Exception do not serialize/deserialize properly:

    Json.NET previous wasn't serializing ISerializable types correctly. The SerializableAttribute is required.

    See here for more info dotnet/corefx#23415.

    And in turn the linked issue dotnet/corefx Issue #23415: PlatformNotSupportedException when attempting to serialize DirectoryInfo instance with Newtonsoft.Json indicates that the change was made at the request of the .NET Core team:

    JamesNK commented on Aug 29, 2017

    So the issue is Json.NET is checking that a type implements ISerializable but not also checking for the SerialiazableAttribute?

    ViktorHofer commented on Aug 29, 2017

    Correct :)

    Thus if you do use PreferISerializableContractResolver instead of marking your ISerializable types with [Serializable], you might encounter this very issue in .NET Core.

    0 讨论(0)
提交回复
热议问题