【问题标题】:Error in Json Serialization "There is already an open DataReader associated with this Command"Json 序列化错误“已经有一个打开的 DataReader 与此命令关联”
【发布时间】:2015-07-27 04:01:47
【问题描述】:

Json 序列化命令给出了这个错误。我使用Newtonsoft.Json 来避免序列化时的循环引用错误。

private IQueryable<Study> GetStudiesData()
{
    var currUser = UserManager.FindById(User.Identity.GetUserId());
    var currUserRole = currUser.Roles.First();

    IQueryable<Study> studies;
    if (User.IsInRole("SuperAdmin")) {
        studies = db.Studies; //all studies from all centers 
    }
    else {
        var assignedStudies = db.Studies.Where(s => s.AssignedUserID == currUser.Id);

        studies = db.Studies.Where(s => s.User.CenterId == currUser.CenterId && s.RoleID == currUserRole.RoleId)
            .Concat(assignedStudies);
    }

    return studies;
}

//ajax call to this function gives error
public ActionResult GetStudies(int pageSize = 10, int pageNum = 1)
{
    var studies = GetStudiesData();
    var studiesCount = studies.Count();
    var studiesPaged = studies.OrderBy(s=>s.PatientID).Skip(pageSize*pageNum).Take(pageSize);

    var result = new { TotalRows = studiesCount, Rows = studiesPaged };

    //this line gives error
    //There is already an open DataReader associated with this Command which must be closed first.
    var data = Newtonsoft.Json.JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.None,
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    });

    return Json(data, JsonRequestBehavior.AllowGet);
}

我在var data = Newtonsoft.Json.JsonConvert.SerializeObject(result, ...) 中尝试了result = studiesresult = studiesPagedresult = studiesCount。 只有studiesPaged 给出了错误。

我可以使用MultipleActiveResultSets=True; 解决它,但我在哪里进行第二个查询?

更新

public ActionResult GetStudies(int pageSize = 10, int pageNum = 1) { var 研究 = GetStudiesData().ToList(); //已解决,创建了另一个问题 //其他代码 }

现在返回的 Json 看起来像是再次将 Json 序列化为字符串。

"{\"TotalRows\":5,\"Rows\":[{\"AssignedUser\":null, ..... }]}"

当被 javascript 解析时,它被分割成一个字符数组。

更新2

改变了

//data is a json string after serialization
return Json(data, JsonRequestBehavior.AllowGet); //Serializing the Json

return Content(data, "application/json");

【问题讨论】:

  • 您是否尝试将其分配给列表,这应该会强制关闭连接。
  • @nik0lias 分配解决了问题,但返回的 json 看起来像序列化了两次。

标签: c# asp.net asp.net-mvc serialization datareader


【解决方案1】:

将它分配给一个列表,然后查询它应该可以防止这种情况:

public ActionResult GetStudies(int pageSize = 10, int pageNum = 1)
{
    var studies = GetStudiesData().ToList();
    var studiesCount = studies.Count();
    var studiesPaged = studies.OrderBy(s=>s.PatientID).Skip(pageSize*pageNum).Take(pageSize);

    var result = new { TotalRows = studiesCount, Rows = studiesPaged };

    //this line gives error
    //There is already an open DataReader associated with this Command which must be closed first.
    var data = Newtonsoft.Json.JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.None,
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    });

    return Json(data, JsonRequestBehavior.AllowGet);
}

【讨论】:

  • 接收到的 json 被读取为所有单个字符。如果我在选项卡中单独打开 json,它会正常读取。那个json有什么问题?
  • 因为 ToList() 将其分配给新集合并强制关闭 DataReader。
  • 您是通过 Ajax 还是类似的方式调用它?当你说一个新标签时,这是你自己打开然后手动输入的网址吗?
  • 我用 Ajax 调用它,我使用新标签查看返回的 json 有什么问题
  • 我只能假设传递给 Ajax 调用的参数会影响结果?
【解决方案2】:
var assignedStudies = db.Studies.Where(s => s.AssignedUserID == currUser.Id);

studies = db.Studies.Where(s => s.User.CenterId == currUser.CenterId && 
              s.RoleID == currUserRole.RoleId).Concat(assignedStudies);

您对DbSet&lt;Studies&gt; 有两个查询

【讨论】:

  • 但是如果我不进行分页 TakeSkip ,它可以正常工作
  • 尝试了不同的 pagenum*pagesize 值。任何导致没有数据的值都可以正常运行并返回空 json
  • 替换为单个查询但错误仍然存​​在studies = db.Studies.Where(s =&gt; (s.User.CenterId == currUser.CenterId &amp;&amp; s.RoleID == currUserRole.RoleId) || s.AssignedUserID == currUser.Id);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多