This is a migrated thread and some comments may be shown as answers.

Handling Circular Reference in EF and DataSourceResult

2 Answers 458 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Pierre
Top achievements
Rank 2
Iron
Iron
Pierre asked on 18 Sep 2018, 08:19 PM

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 Answers, 1 is accepted

Sort by
0
Angel Petrov
Telerik team
answered on 20 Sep 2018, 10:22 AM
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.
0
Pierre
Top achievements
Rank 2
Iron
Iron
answered on 20 Sep 2018, 03:14 PM

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; }
Tags
Grid
Asked by
Pierre
Top achievements
Rank 2
Iron
Iron
Answers by
Angel Petrov
Telerik team
Pierre
Top achievements
Rank 2
Iron
Iron
Share this question
or