Контекст

У меня есть класс для сериализации и десериализации с помощью Newtonsoft.Json.

Моя идея состоит в том, чтобы установить значения по умолчанию для некоторых полей в конструкторе, поэтому во время десериализации, если значение отсутствует, предполагается значение по умолчанию. Однако, к моему удивлению, десериализатор не заменит значение по умолчанию на значение в строке JSON.

Код

public class MyClass {

    public int Key { get; set; }

    private void LoadDefaults() {
        Key = 1;
    }

    public MyClass() {
        LoadDefaults();
    }
}

После сериализации экземпляра из класса выше я получаю этот JSON:

{    "Key": 2    }

Затем я де-сериализую его, используя это:

public void Deserialize(Stream input, out MyClass output) {
    using (var sr = new StreamReader(input)) {
        using (var jr = new JsonTextReader(sr)) {
            var serializer = new JsonSerializer();
            output = serializer.Deserialize<MyClass>(jr);
        }
    }
}

Я ожидаю, что десериализатор сначала вызовет конструктор MyClass, который, в свою очередь, вызывает LoadDefaults (); Кажется, все происходит так, как ожидалось. Но затем, после завершения работы конструктора, я ожидаю, что десериализатор заменит значение по умолчанию Key = 1 (установленное внутри конструктора) на значение, десериализованное из строки JSON, равное 2. Проблема в том, что свойство Key десериализованного объект "output" имеет значение 1 вместо 2.

Почему так происходит? Пропускает ли десериализатор ненулевые свойства после создания объекта?

Онлайн-пример (.NET Fiddle)

https://dotnetfiddle.net/P5GguD

0
Giovani Luigi 1 Сен 2020 в 05:53

2 ответа

Лучший ответ

Вы пропустили указание типа кодировки в StreamReader. В результате поток не был построен должным образом.

using (var sr = new StreamReader(textStream,Encoding.Unicode)) //Provide encoding as Unicode
{
    using (var jr = new JsonTextReader(sr))
    {
        var serializer = new JsonSerializer();
        output = serializer.Deserialize<MyClass>(jr);
    }
}
1
Durga Prasad 1 Сен 2020 в 03:37

Десериализовал его напрямую, зачем устанавливать его в StreamReader? Вы можете десериализовать его напрямую, используя строковое значение JSON, возвращаемое сериализацией.

var mc = new MyClass(){Key = 2};
var json = JsonConvert.SerializeObject(mc);

Console.WriteLine("Serialized Key is: " + mc.Key);

MyClass output = JsonConvert.DeserializeObject<MyClass>(json);
        
Console.WriteLine("De-serialized Key is: " + output.Key);
1
tontonsevilla 1 Сен 2020 в 03:16