通过MVC控制器返回序列化为JSON的大型集合

时间:2014-05-31 10:49:30

标签: c# asp.net-mvc json linq collections

我有一个非常大的结果集,我想使用JSON返回Ajax调用。

我开始创建一个对象集合,然后序列化集合,但集合创建会抛出System.OutOfMemoryException。

我现在尝试更改实现以在没有集合的情况下流式传输JSON,但我仍然得到System.OutOfMemoryException。

这是我目前的代码片段。

  using (var stream = new MemoryStream())
  {
      using (var streamWriter = new StreamWriter(stream))
      {
          using (var jsonWriter = new JsonTextWriter(streamWriter))
          {
              var serializer = new JsonSerializer();

              serializer.Serialize(jsonWriter,new { pins = MakePins(model), missingLocations = 0 });

              jsonWriter.Flush();
          }
      }

  stream.Seek(0, SeekOrigin.Begin);

  return new FileStreamResult(stream, "application/json");

MakePins功能如下所示:

var pinData = _geographyService.GetEnumerationQueryable()
                .SelectMany(x => x.EnumeratedPersonRoleCollection)
                .ApplyFilter(model).Where(x => x.EnumerationCentre.Location != null)
                .AsNoTracking()
                .AsEnumerable();

return pinData.Select(item => new MapPin
    {
        Id = item.EnumerationCentre.EnumerationCentreUid.ToString(),
        Name = item.Person.FullName,
        FillColour = GetMapPinColour(item, model),
        Latitude = item.EnumerationCentre.Location.Latitude,
        Longitude = item.EnumerationCentre.Location.Longitude,
        Count = item.IssuedVoucherCollection.Count()
    });

我尝试过使用yield return而不是select,但OutOfMemoryException是使用Select函数抛出的。

我已经完成了一些谷歌搜索,但还是看不出我还能尝试什么。

1 个答案:

答案 0 :(得分:1)

您当前的解决方案仍然存在同样的问题,因为在返回之前您收集并将所有数据存储在内存流中

您可以通过以下方式尝试:

public ActionResult RobotsText() {
    Response.ContentType = "application/json";

    Response.Write("[");

    foreach(var item in Items)
    {
         Response.Write(JsonSerializer.Serialize(item));

        if ( /*not last*/)
        {
            Response.Write(",");
        }
    }

    Response.Write("]");   

    return new EmptyResult();
}