反序列化 Newtonsoft.Json 中的自定义异常

451

free vpn 本文介绍了反序列化 Newtonsoft.Json 中的自定义异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧! vpn下载

问题描述

我在 Newtonsoft.Json free vpn 版本 vpn下载 11.0.2 中反序列化自定义异常时遇到问题.它在 Newtonsoft.Json 版本 10.0.3 中运行良好.

I've been having trouble deserializing custom exceptions vpn下载 in Newtonsoft.Json 免费vpn version 11.0.2. It works fine vpn free in Newtonsoft.Json version 10.0.3.

我序列化和反序列化使用 -

I 免费vpn serialize and deserialize using - 免费vpn

result = JsonConvert.SerializeObject( <<object of type MyHttpException>> );
MyHttpException deserializedException = JsonConvert.DeserializeObject<MyHttpException>(result);

我在反序列化过程中遇到的错误是 Newtonsoft.Json.JsonSerializationException:

The error I get during deserialization is vpn下载 a Newtonsoft.Json.JsonSerializationException:

找不到用于 MyHttpException 类型的构造函数.一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有 JsonConstructor 属性的构造函数.路径HttpStatusCode",第 2 行,位置 19.

Unable 免费vpn to find a constructor to use for type MyHttpException. A class should either have a default constructor, vpn下载 one constructor vpn下载 with arguments or a constructor marked with the JsonConstructor attribute. Path 'HttpStatusCode', line 2, position 19.

如果我向 MyHttpException 和 MyBaseException 添加无参数构造函数,我不会得到任何异常.但是 InnerException 免费vpn 没有反序列化,为空.

If I add a parameterless constructor to MyHttpException and vpn下载 MyBaseException, I don't get any exception. But the InnerException is not deserialized and is null.

我有什么明显的遗漏吗?我不确定为什么这会在 10.0.3 中工作并在 11.0.2 中中断.

Is there something obvious I'm missing? I'm not sure why 免费vpn下载 this 免费vpn would work in 10.0.3 and free vpn break in 11.0.2.

我的异常类——

public vpn下载 sealed class MyHttpException : MyBaseException
{
  vpn free   public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode)
        : base(MyStatusCode) => HttpStatusCode = httpStatusCode;

 vpn下载  vpn free   public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, string message)
        : base(MyStatusCode, message) => HttpStatusCode = httpStatusCode;

    public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, Exception innerException)
        vpn free : base(MyStatusCode, innerException) => HttpStatusCode = httpStatusCode;

    public MyHttpException(HttpStatusCode httpStatusCode, int MyStatusCode, 免费vpn string 免费vpn下载 message, Exception innerException)
        : base(MyStatusCode, message, innerException) => HttpStatusCode = httpStatusCode;

    免费vpn下载 [SecurityPermission(SecurityAction.Demand, 免费vpn下载 SerializationFormatter = true)]
  免费vpn   private MyHttpException(SerializationInfo info, StreamingContext context)
        : base(info, context) => HttpStatusCode = 免费vpn下载 (HttpStatusCode)info.GetValue("HttpStatusCode", typeof(HttpStatusCode));

    public HttpStatusCode HttpStatusCode { get; set; }

 免费vpn    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
   vpn下载  public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == free vpn null)
        {
 free vpn   免费vpn          throw new 免费vpn ArgumentNullException("info");
        }

        info.AddValue("HttpStatusCode", HttpStatusCode);

   free vpn      // MUST call through 免费vpn下载 to the base class to let vpn下载 it save its 免费vpn own state
 vpn下载        base.GetObjectData(info, context);
    }
}

public 免费vpn下载 abstract class MyBaseException : Exception
{
    public MyBaseException(int MyStatusCode) => this.MyStatusCode = MyStatusCode;

    public MyBaseException(int MyStatusCode, string message)
        : vpn free base(message) => this.MyStatusCode = MyStatusCode;

    public MyBaseException(int MyStatusCode, Exception innerException)
        : base("MyErrorCode: " + MyStatusCode + ". " + MyStatusCodes.GetDescription(MyStatusCode) + ". " + innerException.Message, innerException) => this.MyStatusCode = MyStatusCode;

    public MyBaseException(int MyStatusCode, string message, Exception innerException)
        : base(message, innerException) => 免费vpn this.MyStatusCode = MyStatusCode;

    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
    protected MyBaseException(SerializationInfo info, StreamingContext context)
   免费vpn      : base(info, context)
   vpn下载  {
        MyStatusCode = info.GetInt32("MyStatusCode");
 vpn free    }

   vpn free  public int MyStatusCode { get; set; }

    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
 vpn下载    public override void GetObjectData(SerializationInfo info, StreamingContext context)
 免费vpn    {
        if (info == null)
  vpn free       {
        free vpn    免费vpn下载  throw new ArgumentNullException("info");
     免费vpn    }

        info.AddValue("MyStatusCode", MyStatusCode);

        // MUST call through to the base class to let it save its own state
  免费vpn       base.GetObjectData(info, context);
    }
}

谢谢

推荐答案

在 Json.NET 11 free vpn 中,对 ISerializable 类型的序列化方式进行了更改.根据 发行说明:

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

  • 更改 - 实现 免费vpn下载 ISerializable 但没有 [SerializableAttribute] 的类型不使用 ISerializable 序列化

因此,您现在必须使用 SerializableAttribute 标记您的异常类型:

Thus you must now mark your vpn下载 exception types with SerializableAttribute:

[Serializable]
public sealed class MyHttpException : MyBaseException
{
}

[Serializable]
public abstract 免费vpn class MyBaseException : Exception
{
}

或者,您可以创建一个 vpn下载 自定义合同解析器,以恢复旧行为:

Alternatively, vpn下载 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);

  免费vpn       if (!IgnoreSerializableInterface
            && contract is JsonObjectContract
            && typeof(ISerializable).IsAssignableFrom(objectType)
     免费vpn        && vpn free !objectType.GetCustomAttributes(true).OfType<JsonContainerAttribute>().Any())
        {
    vpn下载     vpn下载     free vpn contract = CreateISerializableContract(objectType);
        }

   vpn下载      return contract;
    }
}

(您可能希望缓存合约解析器以获得最佳性能.)

为什么要进行此更改?根据 问题 #1622:派生自 System.Exception 的类不能正确序列化/反序列化:

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

Json.NET 以前没有正确序列化 ISerializable 类型.SerializableAttribute 是必需的.

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

查看此处了解更多信息dotnet/corefx#23415.

See here for more info dotnet/corefx#23415.

依次链接的问题 dotnet/corefx 问题 #23415:PlatformNotSupportedException vpn下载 尝试序列化 DirectoryInfo 时带有 Newtonsoft.Json 的实例表明更改是应 .NET Core 团队的要求进行的:

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

JamesNK 于 2017 年 8 月 29 日发表评论

JamesNK commented on Aug 29, 免费vpn 2017

所以问题是 Json.NET 正在检查一个类型是否实现了 ISerializable 但不检查 SerialiazableAttribute?

So the issue is 免费vpn下载 Json.NET is checking that a type implements ISerializable but not also checking for the SerialiazableAttribute?

ViktorHofer 于 2017 年 8 月 29 日发表评论

ViktorHofer commented on Aug 29, 2017

正确:)

因此,如果您确实使用 PreferISerializableContractResolver 而不是使用 [Serializable] 标记您的 ISerializable 类型,您可能会在 .NET 中遇到这个问题核心.

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

这篇关于反序列化 Newtonsoft.Json 中的自定义异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

C# 中的多播委托奇怪行为?
Multicast delegate weird behavior in C#?(C# 中的多播委托奇怪行为?)...
2023-11-11 C#/.NET开发问题
6

参数计数与调用不匹配? free vpn
Parameter count mismatch with Invoke?(参数计数与调用不匹配?)...
2023-11-11 免费vpn C#/.NET开发问题
免费vpn 26

如何将代表存储在列表中
How to store delegates in a List(如何将代表存储在列表中)...
2023-11-11 C#/.NET开发问题
6

代表如何工作(在后台)? free vpn
How delegates work (in the vpn free background)?(代表如何工作(在后台)?)...
2023-11-11 C#/.NET开发问题
5

没有 EndInvoke 的 C# 异步调用? free vpn
C# Asynchronous call without EndInvoke?(没有 EndInvoke vpn free 的 C# 异步调用?)...
2023-11-11 C#/.NET开发问题
2

Delegate.CreateDelegate() 和泛型:错误绑定到目标方法
Delegate.CreateDelegate() and generics: Error binding to target method(Delegate.CreateDelegate() 和泛型:错误绑定到目标方法)...
2023-11-11 C#/.NET开发问题
14