当前位置: 代码迷 >> 综合 >> 这么简单的序列化 System.Text.Json.Serialization 也报错了?
  详细解决方案

这么简单的序列化 System.Text.Json.Serialization 也报错了?

热度:74   发布时间:2024-01-12 08:33:58.0

咨询区

  • kofifus

我准备将项目中的 JSON.NET 切换到原生的 System.Text.Json,但我遇到了个意外报错,测试代码如下:


using System.Text.Json.Serialization;
using Newtonsoft.Json;public class C {public C(string PracticeName) { this.PracticeName = PracticeName; }public string PracticeName;
}var x = new C("1");
var json = JsonConvert.SerializeObject(x); // returns "{\"PracticeName\":\"1\"}"var x1 = JsonConvert.DeserializeObject<C>(json); // correctly builds a Cvar x2 = System.Text.Json.Serialization.JsonSerializer.Parse<C>(json);

上面代码的最后一行将会报:


Exception thrown: 'System.NullReferenceException' in System.Text.Json.dll Object reference not set to an instance of an object.

请问我这是哪里做错了?

我发现可以通过 无参构造函数 来解决这个问题,但这样做的话就本末倒置了,请问是否有变通的方法实现原来 JSON.Net 就能实现的简单功能。

回答区

  • Christian Gollhardt

.NET Core 3.0 阶段,System.Text.Json 的开发工作还没有完全结束,目前阶段只支持无参构造函数,可能也许在未来会支持吧。

如果你是将老的版本迁移到 .NET Core 3.0 的话,我还是建议你用 Newtonsoft.Json

  1. MVC

从 Nuget 上安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包,然后将其注入到 services 容器中。


services.AddMvc().AddNewtonsoftJson();
  1. SignalR:

从 Nuget 上安装 Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson 包。


//Client
new HubConnectionBuilder()
.WithUrl("/chatHub")
.AddNewtonsoftJsonProtocol(...)
.Build();//Server
services.AddSignalR().AddNewtonsoftJsonProtocol(...);

这样的话就可以在 .NET Core 3.0 中使用 Json.NET 啦。

  • user11400447

要想解决这个问题,你必须做两点改动:

  1. PracticeName 要做成属性,而不是一个字段。

  2. 使用无参构造函数。

我写了一个控制台程序,其中 C1 通过 Newtonsoft.Json 转换, C2 通过 System.Text.Json


using Newtonsoft.Json;namespace TestJsonParse
{class Program{static void Main(string[] args){var c1 = new C1("1");var json1 = JsonConvert.SerializeObject(c1); // returns "{\"PracticeName\":\"1\"}"var x1 = JsonConvert.DeserializeObject<C1>(json1); // correctly builds a C1var c2 = new C2();string json2 = "{\"PracticeName\":\"1\"}";var x2 = System.Text.Json.Serialization.JsonSerializer.Parse<C2>(json2); // correctly builds a C2}class C1{public C1(string PracticeName) { this.PracticeName = PracticeName; }public string PracticeName;}class C2{public C2() { }public string PracticeName { get; set; }}}
}

点评区

时过境迁,我已经 System.Text.Json 都搞定了,然后我用了最新的 .NET 5 跑题主的代码。


namespace ConsoleApp3
{class Program{static void Main(string[] args){var json = "{\"PracticeName\":\"1\"}";//json.netvar x1 = JsonConvert.SerializeObject(json);//System.Text.Jsonvar x2 = System.Text.Json.JsonSerializer.Deserialize<C>(json);}}public class C{public C(string PracticeName) { this.PracticeName = PracticeName; }public string PracticeName;}
}

结果是。。。。继续报错。。。

这我还能说什么呢...

  相关解决方案