无法将有效的JSON反序列化为具有通用IEnumerable <T>属性的类

时间:2020-07-07 10:34:08

标签: c# json system.text.json

我目前正在努力将接收到的JSON反序列化为具有IEnumerable<T>数据属性的DTO对象。使用ASP.NET Core 3.1和System.Text.Json 4.7.0。

在下面显示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"
}

并且我正在尝试通过使用以下命令将此数据反序列化为以下Dto:

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

第一种ReadAsAsync方法正确地反序列化除数据外的所有其他属性。其次,responseData2反序列化仅产生空属性。

Dto类:

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

2 个答案:

答案 0 :(得分:2)

您的json带有尾随逗号("name": "random1", "name": "random2",),如果无法更改,则需要明确允许,例如:

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

还要在PropertyNameCaseInsensitive上将true设置为JsonSerializerOptions或用具有相应名称的JsonPropertyNameAttribute标记属性(也需要向Data属性添加公共设置器)在PagedResponse上,因为目前不支持internal and private property setters and getters)。例如:

public class PagedResponse<T>
{
    [JsonPropertyName("data")]
    public IEnumerable<T> Data { get; set; }
}

答案 1 :(得分:1)

Data属性没有公共设置程序,因此序列化程序不会分配它。

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

在第二种情况下,您还应该向序列化程序传递忽略属性名称大小写的选项:

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