无法使用通用 IEnumerable<T> 属性 将有效 JSON 反序列化为 class

Unable to deserialize valid JSON into a class with generic IEnumerable<T> property

我目前正在努力将收到的 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; }
}

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

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

同时在 JsonSerializerOptions 上将 PropertyNameCaseInsensitive 设置为 true 或用 JsonPropertyNameAttribute 标记相应名称的属性(您还需要添加 public setter 到 Data 属性 on PagedResponse 因为目前不支持 internal and private property setters and getters)。例如:

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

Data属性没有publicsetter,所以序列化程序不会分配它。

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

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

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