Исключение разбора JSON с System.Text.Json.Serialization - PullRequest
1 голос
/ 07 июня 2019

Мой пример кода очень прост:

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.NullReferenceException в System.Text.Json.dll Ссылка на объект не установлена ​​для экземпляра объекта.

Что я делаю не так?

(Обратите внимание, что это последняя версия .NET Core 3 Preview 5 с последней версией System.Text.Json 4.6.0-preview6.19259.10)

Добавление конструктора без параметров предотвращает исключение, однако я не хочу / не нуждаюсь в конструкторе без параметров, и Json.Net без него хорошо разбирает.

Есть ли способ заставить System.Text.Json анализировать, используя заданный конструктор, как это делает Json.Net?

Ответы [ 2 ]

4 голосов
/ 07 июня 2019

В своем текущем состоянии поддержка JSON в .NET Core 3.0 еще не завершена , и кажется, что поддерживается только конструктор без параметров.Может случиться так, что эта функция будет добавлена ​​в будущем.

Один вариант обходного пути будет заключаться в создании беспараметрического конструктора для вашей сериализованной модели, когда вы хотите использовать новый Json API из.net Framework.Вероятно, нам вообще не следует использовать конструкторы для простых объектов передачи данных, поэтому я рассматриваю это как вариант, а не как обходной путь.

Если вы ищете способ перехода с более старой версии на .netCore 3.0 или используйте Newtonsoft.Json в любом случае, это задокументировано здесь :

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

Таким образом, вы должны * иметь возможность использовать функции Json.NET в .Net Core 3.0

* Я не установил его, поэтому не могу его протестировать

1 голос
/ 07 июня 2019

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