Search code examples
c#asp.netasp.net-mvcserializationdatareader

Error in Json Serialization "There is already an open DataReader associated with this Command"


Json serialization command is giving this error. I used Newtonsoft.Json to avoid the cyclic reference error on serialization.

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);
}

I tried result = studies, result = studiesPaged, result = studiesCount in var data = Newtonsoft.Json.JsonConvert.SerializeObject(result, ...). Only studiesPaged is giving the error.

I can solve it using MultipleActiveResultSets=True; but where am I doing the second query?

Update

public ActionResult GetStudies(int pageSize = 10, int pageNum = 1) { var studies = GetStudiesData().ToList(); //solved, created another issue //other code }

Now the Json returned looks like a Json is again serialized to string.

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

When parsed by javascript it is all splitted to an array of characters.

Update2

Changed

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

to

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

Solution

  • Assigning it to a list, and then querying it should prevent this:

    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);
    }