【问题标题】:Unable to deserialize valid JSON into a class with generic IEnumerable<T> property无法将有效 JSON 反序列化为具有通用 IEnumerable<T> 属性的类
【发布时间】:2020-07-07 10:34:08
【问题描述】:

我目前正在努力将收到的 JSON 反序列化为具有 IEnumerable&lt;T&gt; 数据属性的 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; }
}

【问题讨论】:

  • 您的OutputDTO 班级是什么样的?反序列化为泛型类有效 - List&lt;T&gt; 就是这样一个类

标签: c# json system.text.json


【解决方案1】:

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

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

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

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

【讨论】:

  • 虽然更好的选择是使用 valid json,而不是尾随逗号。
  • @FranzGleichmann 同意,但有时它超出了我们的控制 =( .
  • 总是可以选择亲自去找那些搞砸了创建有效 json 这样简单的事情的人,并当着他们的面大喊他们应该修复错误的代码.即使如果这无助于解决问题,它也有助于提高个人满意度;)
  • 数组后面的逗号没问题,没有这个设置反序列化就好了。
  • @CodeCaster 在我的机器上抛出异常,也许还有全局设置来改变这种行为。
【解决方案2】:

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

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

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

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

【讨论】:

  • 缺少的公共二传手是关键,我的错误。现在可以了,谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多