我有以下代码表示分页查询的结果。
public class Page<T> : IEnumerable<T>
{
public IEnumerable<T> Source { get; }
public int PageNumber { get; }
public int PageSize { get; }
public int TotalCount { get; }
public int TotalPages => TotalCount / PageSize + (TotalCount % PageSize > 0 ? 1 : 0);
public Page(
IEnumerable<T> source,
int pageNumber,
int pageSize,
int totalCount)
{
Source = source;
PageNumber = pageNumber;
PageSize = pageSize;
TotalCount = totalCount;
}
public IEnumerator<T> GetEnumerator()
{
return Source.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
下面是一个 MVC 控制器方法,它通过 MVC Json 序列化程序(不是 WebAPI 序列化程序(返回一页结果。
[HttpGet, Route("mergeable")]
public async Task<ActionResult> Mergeable([FromUri] Mergeable.Query query)
{
Page<Mergeable.Model> result = await mediator.Send(query);
return Json(result, JsonRequestBehavior.AllowGet);
}
调用时,响应 Json 是 T 数组。所有分页元属性(总计数、页码、页面大小(都不会序列化。
默认的 MVC Json 序列化程序(无论是什么(是否忽略 IEnumerable 实例上的其他属性?如何覆盖此行为?
ASP.NET Web API和 ASP.NET Core MVC(也运行在完整框架上(使用 Json.NET。 Json.NET 还将从实现IEnumerable的对象生成一个数组。
此代码将生成[1,2,3]
var page=new Page<int>(new int[]{1,2,3},1,10,100);
var text=Newtonsoft.Json.JsonConvert.SerializeObject(page);
Json.NET 允许您指定如何通过 JsonObject 或 JsonArray 等属性序列化对象。如果将 JsonObject
属性添加到 Page 类,它将被序列化为:
{"Source":[1,2,3],"PageNumber":1,"PageSize":10,"TotalCount":100,"TotalPages":10}
ASP.NET MVC仍然使用相当旧的JavaScriptSerializer,其描述是:
Json.NET 应使用序列化和反序列化。为启用 AJAX 的应用程序提供序列化和反序列化功能。
您可以将 MVC 配置为使用 ASP.NET Json.NET,如本 SO 问题所示。如果您不想这样做,可以使用 Json.NET 序列化为字符串并返回具有 JSON 内容类型的字符串,例如:
return Content(JsonConvert.SerializeObject(page), "application/json");
这是一个 Json 格式限制,json 格式不支持具有附加属性的 comlex 数组。
实现IEnumerable
对象的 json 序列化行为是忽略其他属性,仅从 GetEnumerator()
进行序列化。
可以使用 Source 属性获取元素并避免Page<T> : IEnumerable<T>
实现。