【问题标题】:Exception parsing json with System.Text.Json.Serialization使用 System.Text.Json.Serialization 解析 json 的异常
【发布时间】:2019-06-07 00:02:38
【问题描述】:

我的示例代码很简单:

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” 对象引用未设置为对象的实例。

我做错了什么?

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

添加无参数构造函数可以防止异常,但是我不想要/不需要无参数构造函数,没有它,Json.Net 解析得很好。

有没有办法让 System.Text.Json 像 Json.Net 一样使用给定的构造函数进行解析?

【问题讨论】:

  • 你试过添加无参构造函数吗?
  • 好的,添加无参数构造函数可以防止异常但是我不想要/不需要无参数构造函数,没有它 json.net 解析很好
  • 我认为,一般来说,无参数构造函数一直是可序列化类型的先决条件。考虑我熟悉的 .NET 场景。 XML序列化等
  • 在我的示例中查看 - Json.NET 没有无参数构造函数没有问题,我也找不到任何需要的文档
  • @BagusTesa,再次如上所示,Json.Net 对我的对象进行淡化没有问题,并且由于只有一个构造函数,因此不需要 [JsonConstructor] 属性

标签: c# .net-core json.net .net-core-3.0 system.text.json


【解决方案1】:

在当前状态下,.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 功能

*我没有安装,所以无法测试

【讨论】:

  • 对我来说AddNewtonsoftJson 方法不会退出。
  • 你是否安装了上面的nuget包并导入了命名空间Microsoft.Extensions.DependencyInjection?还要注意它是IMvcBuilder 上的一个方法,而不是IServiceCollection。您需要将其与AddMvc 一起使用,如上图所示@SaeedNamati
【解决方案2】:

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

【讨论】:

  • 也许您可以发布一个代码示例来说明您建议的解决方案?
  • 谢谢,你是说我不能序列化字段吗?我也不想要一个空的ctor,我的真实案例涉及很多类,其中许多没有空的ctor,而Json.NET对此没有问题。
  • @kofifus 使用 System.Text.Json,似乎是这样(至少就 Parse 方法而言)。
  • 您阅读我的编辑评论了吗?请不要写edit这个词。这只是噪音。我们已经在编辑历史中看到了这一点;)
  • @ChristianGollhardt 对此感到抱歉。还在学习礼仪。
【解决方案3】:

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

您不需要指定版本。如果使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多