这么简单的序列化 System.Text.Json.Serialization 也报错了?
共 5223字,需浏览 11分钟
·
2021-07-28 12:50
咨询区
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 C
var 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
。
MVC
从 Nuget 上安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson
包,然后将其注入到 services
容器中。
services.AddMvc().AddNewtonsoftJson();
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:
要想解决这个问题,你必须做两点改动:
PracticeName
要做成属性,而不是一个字段。使用无参构造函数。
我写了一个控制台程序,其中 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 C1
var 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.net
var x1 = JsonConvert.SerializeObject(json);
//System.Text.Json
var x2 = System.Text.Json.JsonSerializer.Deserialize<C>(json);
}
}
public class C
{
public C(string PracticeName) { this.PracticeName = PracticeName; }
public string PracticeName;
}
}
结果是。。。。继续报错。。。
这我还能说什么呢...