如何将非数组json反序列化为实现List <t>的子类?

时间:2018-07-15 13:18:54

标签: c# json deserialization

我有以下课程:

public class PagedClientModelList<T> : List<T>
{
    public int TotalCount { get; set; }
    public int PageSize { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages { get; set; }
}

两个不同的json字符串将反序列化为该对象的实例:

  • api GET请求的http内容将反序列化为List<T>
  • api GET请求的“ X-Pagination”标头将反序列化为派生类型PagedClientModelList<T>的4个属性

反序列化为List<T>没问题:

var result = JsonConvert.DeserializeObject<PagedClientModelList<Person>>
                 (httpResponseMessage.Content.ReadAsStringAsync().Result);

对于json字符串:

[
  {
    "id": 1,
    "name": "Hans"
  },
  {
    "id": 2,
    "name": "Peter"
  },
  {
    "id": 3,
    "name": "Max"
  }
]

但是,当我要反序列化标头(即非数组json)时,jsonConverter希望再次反序列化为List<T>并引发异常,但是我需要将其序列化为子类{{ 1}}:

PagedClientModelList<T>

对应的标头值:

if (httpResponseMessage.Headers.TryGetValues("X-Pagination", out var xPagination))
{
    result = JsonConvert.DeserializeObject<PagedClientModelList<Person>>(xPagination.First());

    // throws exception: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type [... because it requires json array]
}

如何将非数组json反序列化为实现{ "totalCount": 12, "pageSize": 3, "currentPage": 1, "totalPages": 4 } 的子类?

2 个答案:

答案 0 :(得分:2)

好的,这是另一种选择,可以稍微更改模型:

public class Person
{
    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

public class PagedClientModelList<T> where T : class, new()
{
    [JsonProperty("totalCount")]
    public int TotalCount { get; set; }

    [JsonProperty("pageSize")]
    public int PageSize { get; set; }

    [JsonProperty("currentPage")]
    public int CurrentPage { get; set; }

    [JsonProperty("totalPages")]
    public int TotalPages { get; set; }

    [JsonProperty("content")]
    public List<T> Content { get; set; }

    public PagedClientModelList()
    {
        Content = new List<T>();
    }
}

测试代码:

class Program
{
    static void Main(string[] args)
    {
        string header = @"{
""totalCount"": 12,
""pageSize"": 3,
""currentPage"": 1,
""totalPages"": 4
}";

        string content = @"[
{
    ""id"": 1,
    ""name"": ""Hans""
},
{
    ""id"": 2,
    ""name"": ""Peter""
},
{
    ""id"": 3,
    ""name"": ""Max""
}
]";

        var modelList = JsonConvert.DeserializeObject<PagedClientModelList<Person>>(header);
        modelList.Content = JsonConvert.DeserializeObject<List<Person>>(content);

        Console.ReadKey();
    }
}

答案 1 :(得分:-1)

为了前进,我实现了以下解决方法:

public class PagedClientModelList<T> : List<T>
{
    public PaginationMetadata PaginationMetadata { get; set; }
}

public class PaginationMetadata
{
    public int TotalCount { get; set; }
    public int PageSize { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages  { get; set; }
}

现在我可以反序列化了,没有任何问题:

var result = JsonConvert.DeserializeObject<PagedClientModelList<Person>>
                 (httpResponseMessage.Content.ReadAsStringAsync().Result);

if (httpResponseMessage.Headers.TryGetValues("X-Pagination", out var xPagination))
{
    result.PaginationMetadata = JsonConvert.DeserializeObject<PaginationMetadata>(xPagination.First());
}