使用System.Text.Json.Serialization解析json的异常

时间:2019-06-07 00:02:38

标签: c# .net-core json.net asp.net-core-signalr .net-core-3.0

我的示例代码非常简单:

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);

最后一行出现:

  

引发的异常:System.Text.Json.dll中的“ System.NullReferenceException”   对象引用未设置为对象的实例。

我在做什么错了?

(请注意,这是在具有最新System.Text.Json 4.6.0-preview6.19259.10的最新.NET Core 3预览5上)

添加无参数的构造函数可防止异常,但是我不希望/不需要无参数的构造函数,而Json.Net可以很好地解析它。

是否有一种方法可以像Json.Net一样使用给定的构造函数来解析System.Text.Json?

3 个答案:

答案 0 :(得分:3)

在当前状态下,.NET Core 3.0 is still not finished中的JSON支持,并且似乎仅支持无参数构造函数。将来可能会添加该功能。

一个解决方法选项是当您要使用.net框架中的新Json API时,为序列化模型创建无参数构造函数。也许我们根本不应该为简单的数据传输对象使用构造函数,因此我将其视为选项,而不是解决方法。

如果您搜索如何从较早版本迁移到.net core 3.0或仍然使用Newtonsoft.Json的方法,则会在here中进行记录:

MVC

安装Microsoft.AspNetCore.Mvc.NewtonsoftJson软件包,并将其注册到您的服务中:

services.AddMvc().AddNewtonsoftJson();

SignalR

安装Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson软件包

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

//Server
services.AddSignalR().AddNewtonsoftJsonProtocol(...);

那样,您应该*能够在.Net Core 3.0中使用Json.NET功能

*我尚未安装,所以无法测试

答案 1 :(得分:1)

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

答案 2 :(得分:1)

System.Text.Json.Serialization 的 Json 支持非常不稳定。最好使用 NewtonSoft.Json,因为它更稳定,几乎每个人都使用它。如果运行控制台应用程序,则从终端中的文件夹执行 enter image description here

不过,您不需要指定版本。如果使用 Visual Studio,则使用 Nuget 包管理器安装 Newtonsoft.json。

从文件中读取 json,例如 data.json

{
  "Name":"Logan",
  "Age": 30
  "Books": ["Infinity War", "End Game"]
}

指定您的属性示例

class Person
{
  public string Name{get; set;}
  public int Age{get; set;}
  public IList<string> Books{get; set;}
}

然后从您希望访问 json 数据的类执行以下操作

string fileContent = System.IO.File.ReadAllText(@"./data.json");
Person person = Newtonsoft.Json.JsonConverter.DeserializeObject<Person>(fileContent);

测试一下

Console.WriteLine($"Hi {person.Name} you are {person.Age} today read {person.Books[0]}");

有关详细信息,请访问 https://www.newtonsoft.com/json/help/html/DeserializeObject.htm