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

DotNetCore实战

共 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

  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 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 { getset; }
        }
    }
}

点评区

时过境迁,我已经 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;
    }
}

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

这我还能说什么呢...

浏览 45
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报