Handling Circular Reference in EF and DataSourceResult

3 posts, 0 answers
  1. Pierre
    Pierre avatar
    260 posts
    Member since:
    Apr 2007

    Posted 18 Sep 2018 Link to this post

    HI, I try to search and I can't found a way to handling the circular reference error caused when serialize DataSourceResult containing EF FK with Include.

    For exemple my 2  EF class:

    public class ActionGES
     {
         public int ActionGESID { get; set; }
         [Required]
         public int MunicipaliteId { get; set; }
         [MaxLength(250), Required]
         public string Titre { get; set; }
         [Required]
         public string Description { get; set; }
         [Required]
         public int AnneeDepart { get; set; }
         [Required]
         public int AnneeCible { get; set; }
         [Required]
         public int ObjectifCible { get; set; }
         [Required]
         public string UniteIndicateur { get; set; }
         public ICollection<IndicateurAction> Indicateurs { get; set; }
     
         public int SecteurId { get; set; }
         public Secteur Secteur { get; set; }
     
         public int Ordre { get; set; }
         public string FormuleGES { get; set; }
         public string ImageUrl { get; set; }
         public bool ApprouveEA { get; set; }
     
         [Required]
         public bool Archive { get; set; }
     
     
     }
     
     public class IndicateurAction
     {
         public int IndicateurActionID { get; set; }
         [Required]
         public int Indicateur { get; set; }
         [Required]
         public int Annee { get; set; }
         public bool ApprouveEA { get; set; }
     
         //FK Key
         public int ActionGESId { get; set; }
         public ActionGES ActionGES { get; set; }
     }

    The EF line for the Get (called be the controller)

    var ctx = new PortailGESContext();
    Actions = ctx.Actions.Where(a => a.Archive == false & a.MunicipaliteId == MunicipaliteId).OrderBy(o => o.Ordre).Include(s=>s.Secteur).Include(s => s.Indicateurs);

    Then the controller action:

    //GET: ActionSommaire_Read
    [Authorize]
    public async Task<ActionResult> Actions_ReadAsync([DataSourceRequest]DataSourceRequest request)
    {
        IQueryable<ActionGES> actions;
     
        if (Session["MunicipaliteIdSel"] != null && Convert.ToInt32(Session["MunicipaliteIdSel"]) > 0)
        {
            actions = this.actionService.GetActionsActive(Convert.ToInt32(Session["MunicipaliteIdSel"]));
        }
        else
        {
            actions = Enumerable.Empty<ActionGES>().AsQueryable();
            ModelState.AddModelError("Error: no ID...", "");
        }
         
        DataSourceResult dsResult = await actions.ToDataSourceResultAsync(request, ModelState);
     
     
     
        return Json(dsResult, JsonRequestBehavior.AllowGet);           
    }

     

    This give me a circular reference when serializing Json. After reading on the web, I try to add this line to convert myself in JSON before returning it to the view:

    var result = JsonConvert.SerializeObject(dsResult, Formatting.None,
                               new JsonSerializerSettings
                               {
                                   ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                               });

    This time the convertrion work well with out circular reference, but the Json receive by the view is not the same. So the grid do not work.

    Result with Json(result):  {"Data":[{"ActionGESID":1,"MunicipaliteId":1,"Titre":"test" ......
    Result with JsonConvert.SerializeObject:  "{\"Data\":[{\"ActionGESID\":1,\"MunicipaliteId\":1,\"Titre\":\"Test\" .....

    Any idea to handle this?

    Thanks

     

     

  2. Angel Petrov
    Admin
    Angel Petrov avatar
    1102 posts

    Posted 20 Sep 2018 Link to this post

    Hello,

    This is a commonly encountered problem. One thing you can do is disable proxy creation as  suggested here. Another thing that you can try use a third party library for serialization and manually create an object of type DataSourceResult and assign the data to its Data property.

    Regards,
    Angel Petrov
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Pierre
    Pierre avatar
    260 posts
    Member since:
    Apr 2007

    Posted 20 Sep 2018 in reply to Angel Petrov Link to this post

    Thanks for reply. But for now I just use the annotation [ScriptIgnore] on the navigation propertie of the child object and that work.

    [ScriptIgnore]
    public ActionGES ActionGES { get; set; }
Back to Top