You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C# .NET Core中如何反序列化PagedList泛型分页对象?

解决Newtonsoft.Json反序列化泛型PagedList<T>的构造器匹配问题

咱们先拆解下报错的核心原因:Newtonsoft.Json在反序列化时,找不到能和JSON字段对应上的构造器参数。你的PagedList<T>里虽然有标记[JsonConstructor]的构造器,但构造器中的totalRecord参数名,和JSON里的TotalItems字段名不匹配,序列化器没法自动关联这两者,所以抛出了找不到合适构造器的异常。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:修改构造器参数名匹配JSON字段(最直接)

把构造器里的totalRecord参数改成totalItems,让参数名和JSON的键完全一致,序列化器就能自动匹配了。修改后的代码如下:

[JsonConstructor] 
public PagedList(IEnumerable<T> source, int totalItems, int pageNumber, int pageSize) { 
    TotalItems = totalItems; 
    PageNumber = pageNumber; 
    PageSize = pageSize; 
    List = source.ToList(); 
} 

// 如果需要保留IQueryable版本,同样修改参数名并标记JsonConstructor
[JsonConstructor] 
public PagedList(IQueryable<T> source, int totalItems, int pageNumber, int pageSize) { 
    TotalItems = totalItems; 
    PageNumber = pageNumber; 
    PageSize = pageSize; 
    List = source.ToList(); 
}

注意:如果两个构造器都标记[JsonConstructor],序列化器会优先匹配参数类型和数量更贴合JSON数据的那个——你的JSON里List是数组,对应IEnumerable<T>,所以第一个构造器会被优先选中。

方案2:用JsonProperty标记构造器参数指定映射(无需修改参数名)

如果不想改动参数名称,可以给totalRecord参数加上[JsonProperty("TotalItems")],明确告诉序列化器这个参数对应JSON里的哪个字段:

[JsonConstructor] 
public PagedList(IEnumerable<T> source, [JsonProperty("TotalItems")] int totalRecord, int pageNumber, int pageSize) { 
    TotalItems = totalRecord; 
    PageNumber = pageNumber; 
    PageSize = pageSize; 
    List = source.ToList(); 
}

这样即使参数名和JSON键不一致,序列化器也能正确完成映射。

方案3:自定义JsonConverter(适合无法修改原类的场景)

如果你不能修改PagedList<T>的源代码,可以自定义一个转换器手动处理反序列化逻辑:

public class PagedListConverter<T> : JsonConverter<PagedList<T>>
{
    public override PagedList<T> ReadJson(JsonReader reader, Type objectType, PagedList<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var totalItems = jsonObject["TotalItems"].Value<int>();
        var pageNumber = jsonObject["PageNumber"].Value<int>();
        var pageSize = jsonObject["PageSize"].Value<int>();
        var list = jsonObject["List"].ToObject<List<T>>(serializer);
        
        return new PagedList<T>(list, totalItems, pageNumber, pageSize);
    }

    public override void WriteJson(JsonWriter writer, PagedList<T> value, JsonSerializer serializer)
    {
        // 如果需要支持序列化,这里可以补充写入逻辑
        var jsonObject = new JObject
        {
            ["TotalItems"] = value.TotalItems,
            ["PageNumber"] = value.PageNumber,
            ["PageSize"] = value.PageSize,
            ["List"] = JArray.FromObject(value.List, serializer)
        };
        jsonObject.WriteTo(writer);
    }
}

使用时在反序列化方法中指定这个转换器即可:

var pagedList = JsonConvert.DeserializeObject<PagedList<Dvhc>>(jsonString, new PagedListConverter<Dvhc>());

也可以把转换器加入全局序列化设置,让所有PagedList<T>的反序列化都自动使用它。

为什么不能用默认构造器?

你代码里注释了默认构造器,但即使打开它也没法正常工作——因为你的TotalItems、PageNumber等属性都是只读的(只有get;没有set;),Newtonsoft.Json无法给这些只读属性赋值,最终会得到一个所有属性都是默认值的无效对象,所以这条路走不通。

内容的提问来源于stack exchange,提问作者quanchinhong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:12:32