MVC Controller Json序列化实现IEnumerable <t>的类型

时间:2018-03-09 08:42:53

标签: c# json asp.net-mvc

我有以下代码表示分页查询的结果。

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 Serializer(而不是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的数组。所有的分页元属性(TotalCount,PageNumber,PageSize)都没有被序列化。

默认的MVC Json序列化程序(无论是什么)忽略IEnumerable实例上的其他属性?如何覆盖此行为?

2 个答案:

答案 0 :(得分:1)

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允许您指定希望通过JsonObjectJsonArray等属性序列化对象的 方式。如果将JsonObject属性添加到Page类,它将被序列化为:

{"Source":[1,2,3],"PageNumber":1,"PageSize":10,"TotalCount":100,"TotalPages":10}

ASP.NET MVC仍然使用相当旧的JavaScriptSerializer,其描述为:

  

Json.NET应该用于序列化和反序列化。为支持AJAX的应用程序提供序列化和反序列化功能。

您可以将ASP.NET MVC配置为使用Json.NET as shown in this SO question。如果您不想这样做,可以使用Json.NET序列化为字符串并返回带有JSON内容类型的字符串,例如:

 return Content(JsonConvert.SerializeObject(page), "application/json");

答案 1 :(得分:0)

这是Json格式限制,json格式不支持具有其他属性的comlex数组。

实现IEnumerable的对象的json序列化行为是忽略其他属性,只是从GetEnumerator()序列化。

您可以使用Source属性获取元素并避免Page<T> : IEnumerable<T>实现。