0

I am currently struggling to deserialize received JSON into a DTO object which has IEnumerable<T> data property. Using ASP.NET Core 3.1 and System.Text.Json 4.7.0.

Below is displayed the JSON

{
  "data": [
    {
      "alternateId": "2cc688d6-cc51-4501-9320-9e5b6e0b8710",
      "name": "random1",
    },
    {
      "alternateId": "e1c14f81-12fa-4ed8-b5ab-e1f4b9f25401",
      "name": "random2",
    }
  ],
  "pageNumber": 1,
  "pageSize": 2,
  "resultCount": 2,
  "sortColumnName": "Name",
  "orderByType": "Ascending"
}

And I am trying to deserialize this data into the following Dtos by using these commands:

var responseData = await response.Content.ReadAsAsync<PagedResponse<OutputDTO>>();
var responseString = await response.Content.ReadAsStringAsync();
var responseData2 = JsonSerializer.Deserialize<PagedResponse<OutputDTO>>(responseString);

The first ReadAsAsync approach deserializes all other properties correctly except the data. Second, responseData2 deserialization produces only empty properties.

Dto classes:

public class PagedResponse<T>
{
    public IEnumerable<T> Data { get; }

    public PagedResponse()
    {
    }

    public PagedResponse(IEnumerable<T> data)
    {
        Data = data;
    }

    public int? PageNumber { get; set; }
    public int? PageSize { get; set; }
    public int? ResultCount { get; set; }
    public string SortColumnName { get; set; }
    public OrderByType OrderByType { get; set; }
}

public class OutputDTO
{
    public Guid AlternateId { get; set; }

    public string Name { get; set; }
}
ajr
  • 874
  • 2
  • 13
  • 29

2 Answers2

3

Your json has trailing commas ("name": "random1", "name": "random2",), if you can't change it you will need to allow that explicitly, for example:

 JsonSerializer.Deserialize<PagedResponse<OutputDTO>>(json, 
     new JsonSerializerOptions {AllowTrailingCommas = true});

Also set PropertyNameCaseInsensitive to true on JsonSerializerOptions or mark properties with JsonPropertyNameAttribute with corresponding names(also you will need to add public setter to Data property on PagedResponse cause currently internal and private property setters and getters are not supported). For example :

public class PagedResponse<T>
{
    [JsonPropertyName("data")]
    public IEnumerable<T> Data { get; set; }
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    although the better option would be to use _valid json_ instead, without trailing commas. – Franz Gleichmann Jul 07 '20 at 10:43
  • @FranzGleichmann agreed, but sometimes it out of our control =( . – Guru Stron Jul 07 '20 at 10:44
  • 1
    there is _always_ the option of physically going to the person who screwed up such a simple thing as creating valid json and shout in their face that they ought to fix their faulty code. even _if_ that doesn't help with solving the problem, it helps with personal satisfaction ;) – Franz Gleichmann Jul 07 '20 at 10:46
  • The trailing commas in the array are no problem though, it deserializes just fine without this setting. – CodeCaster Jul 07 '20 at 10:47
  • @CodeCaster was throwing exceptions on my machine, maybe there is also global settings to change this behavior. – Guru Stron Jul 07 '20 at 10:49
  • Great point about the invalid JSON, however, my bigger mistake was the missing public setter... Anyways good info on how to deal with the trailing commas. – ajr Jul 07 '20 at 10:56
1

The Data property has no public setter, so the serializer won't assign it.

public IEnumerable<T> Data { get; set;  }

In the second case you should also pass the serializer the option to ignore property name casing:

JsonSerializer.Deserialize<PagedResponse<OutputDTO>>(json,
    new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
CodeCaster
  • 147,647
  • 23
  • 218
  • 272