System.Text.JSON doesn't deserialize what Newtonsoft does
Asked Answered
K

5

28

I have a json that the new System.Text.Json.JsonSerializer.Deserialize<T>(json_data) serialize as List<T> with the correct numbers of elements, but then the objects inside have all the values null or 0

Same json with Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json_data) is correctly filled.

Class:

public class SensorValue
    {
        public string StationCode { get; set; }
        public string SensorCode { get; set; }
        public string SensorNameIt { get; set; }
        public string SensorNameDe { get; set; }
        public string SensorNameLd { get; set; }
        public string SensorUnitMeasure { get; set; }
        public DateTime SamplingDateTime { get; set; }
        public Decimal SamplingValue { get; set; }
    }

JSON

[{"stationCode":"89190MS","sensorCode":"LT","sensorNameIt":"Temperatura dell´aria","sensorNameDe":"Lufttemperatur","sensorNameLd":"Temperatura dl’aria","sensorUnitMeasure":"°C","samplingDateTime":"2019-11-15T15:10:00","samplingValue":0.3},{"stationCode":"89190MS","sensorCode":"N","sensorNameIt":"Precipitazioni","sensorNameDe":"Niederschlag","sensorNameLd":"plueia","sensorUnitMeasure":"mm","samplingDateTime":"2019-11-15T15:10:00","samplingValue":0.4},{"stationCode":"89190MS","sensorCode":"WR","sensorNameIt":"Direzione del vento","sensorNameDe":"Windrichtung","sensorNameLd":"Direzion dl vënt","sensorUnitMeasure":"° ","samplingDateTime":"2019-11-15T15:10:00","samplingValue":165.7},{"stationCode":"89190MS","sensorCode":"WG","sensorNameIt":"Velocità del vento","sensorNameDe":"Windgeschwindigkeit","sensorNameLd":"Slune dl vënt","sensorUnitMeasure":"m/s","samplingDateTime":"2019-11-15T15:10:00","samplingValue":0.7},{"stationCode":"89190MS","sensorCode":"WG.BOE","sensorNameIt":"Velocitá raffica","sensorNameDe":"Windgeschwindigkeit Böe","sensorNameLd":"Slune dl vënt","sensorUnitMeasure":"m/s","samplingDateTime":"2019-11-15T15:10:00","samplingValue":1.3},{"stationCode":"89190MS","sensorCode":"LF","sensorNameIt":"Umidità relativa","sensorNameDe":"relative Luftfeuchte","sensorNameLd":"Tume relatif","sensorUnitMeasure":"%","samplingDateTime":"2019-11-15T15:10:00","samplingValue":100.0},{"stationCode":"89190MS","sensorCode":"LD.RED","sensorNameIt":"Pressione atmosferica","sensorNameDe":"Luftdruck","sensorNameLd":"Druch dl’aria","sensorUnitMeasure":"hPa","samplingDateTime":"2019-11-15T15:10:00","samplingValue":1006.9},{"stationCode":"89190MS","sensorCode":"GS","sensorNameIt":"Radiazione globale ","sensorNameDe":"Globalstrahlung","sensorNameLd":"Nraiazion globala ","sensorUnitMeasure":"W/m²","samplingDateTime":"2019-11-15T15:10:00","samplingValue":3.8},{"stationCode":"89190MS","sensorCode":"SD","sensorNameIt":"Durata soleggiamento","sensorNameDe":"Sonnenscheindauer","sensorNameLd":"Dureda dl surëdl","sensorUnitMeasure":"s","samplingDateTime":"2019-11-15T15:10:00","samplingValue":0.0}]

Any help ? consoleapp project .net core 3.0.0 newtonsoft 12.0.3

enter image description here

Kegan answered 15/11, 2019 at 14:36 Comment(0)
I
88

The default behavior of the System.Text.Json deserializer is to match properties as case sensitive. You need to pass options telling it to match case insensitive:

using System.Text.Json;

JsonSerializer.Deserialize<T>(json_data, new JsonSerializerOptions 
{
    PropertyNameCaseInsensitive = true
});
Impacted answered 15/11, 2019 at 14:45 Comment(1)
Just a heads up about passing a new copy of serializer options every time: performance can suffer: github.com/dotnet/runtime/issues/38982Rocaille
H
11

For setting globally, in Program.cs / Startup.cs set

services.AddControllers(options =>
{
    //...
}).AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Default;
});
Hurlyburly answered 2/2, 2021 at 23:32 Comment(1)
This answer did not work for me as I was using it in my .net core api. I had to pass the options in the Deserialize method itseelf.Juncture
T
4

I had a problem getting default values instead of real ones. When I forgot to add an identifier to the properties of the model in the current project (set). Prior to using serialization/deserialization, only the identifier (get) was required for properties in the model. But for me both libraries (System.Text.Json and NewtonSoft )returned the default value. This is not the case of the topic starter.

Tucket answered 11/2, 2022 at 13:57 Comment(2)
Thanks! I spent too much time figuring out why all my properties are "null" even when using "PropertyNameCaseInsensitive = true". Turned out it was because the class properties did not have "set".Eyeopener
You have no idea how much time I wasted on this!Mathematics
E
1
if (response.IsSuccessStatusCode)
{
   var json = await response.Content.ReadAsStringAsync();

   var options = new JsonSerializerOptions
   {
       WriteIndented = true,
       PropertyNameCaseInsensitive = true // this is the point
   };

   var books = JsonSerializer.Deserialize<IEnumerable<Book>>(json, options);
}
Eames answered 25/1, 2021 at 1:16 Comment(0)
E
1

You can also apply JsonPropertyName attributes to the model properties.

[JsonPropertyName("yourSourceJsonKey")]
public string YourPropertyName { get; set; }

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties#customize-individual-property-names

This article describes the behaviour of the serialiser:

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-core-3-1#serialization-behavior

Elka answered 20/6, 2021 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.