This is a migrated thread and some comments may be shown as answers.
A circular reference was detected while serializing an object of type
3 Answers 415 Views
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
oliwa
Top achievements
Rank 1
oliwa asked on 15 Dec 2011, 06:00 AM
Hey there,

I have a database that I have reverse engineered using OpenAccess.  I'm using MVC3 and writing my web site in C#.  I have a grid defined as follows...

@{
    Html.Telerik().Grid<Training>()
        .Name("TrainingGrid")
        .DataBinding(x =>
                        {
                            x.Ajax().Select("GetGridData", "Training");
                            x.Ajax().Update("UpdateGridData", "Activity");
                            x.Ajax().Insert("InsertGridData", "Activity");
                            x.Ajax().Delete("DeleteGridData", "Activity");
                        }
        )
        .Columns(x =>
                    {
                        x.Bound(y => y.TrainingStatus.TrainingStatusName).Title("Status");
                        x.Bound(y => y.RepCategory.RepCategoryName).Title("REP Category");
                        x.Bound(y => y.TrainingDate).Format("{0:MM/dd/yyyy}").Title("Training Date");
                        x.Bound(y => y.Activity);
                        x.Bound(y => y.Purpose);
                        x.Bound(y => y.NumOfHours).Format("{0:#,##0.00}").Title("Hours");
                        x.Command(y => y.Edit().ButtonType(GridButtonType.Image));
                        x.Command(y => y.Delete().ButtonType(GridButtonType.Image));
                    }
        )
        .ToolBar(x => x.Insert().ButtonType(GridButtonType.Image))
        .DataKeys(x => x.Add(y => y.TrainingId))
        .Pageable(x =>
                    {
                        x.PageSize(5);
                        x.Style(GridPagerStyles.Numeric);
                    })
        .Sortable(x => x.OrderBy(y => y.Add(z => z.UpdateDate).Descending()))
        .Render();
}

If I use server binding everything works but when I use ajax binding I get the exception listed below.  Based on the stack trace it appears to be a limitation of the JSON serializer built into MVC and I noticed the circular reference changed as I took away navigation properties from my OpenAccess model to eliminate the circular references but doing so greatly limits my future capabilities.

Is there another trick I could use?  I contemplated creating a view model but I don't want to reproduce a lot of code.

Server Error in '/' Application.

A circular reference was detected while serializing an object of type 'Data.School'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'Data.School'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: A circular reference was detected while serializing an object of type 'Data.School'.]
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1549
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1380
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1424
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1424
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1424
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1424
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1380
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeDictionary(IDictionary o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +527
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1319
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +26
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +74
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +6
   System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +216
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
   System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
   System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963149
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.237

3 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 16 Dec 2011, 06:00 PM
Hello Oliwa,

Unfortunately there is no clean solution. The troubleshooting help topic of the Grid lists the known workarounds.

Kind regards,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now
0
oliwa
Top achievements
Rank 1
answered on 17 Dec 2011, 07:12 AM
I think that with a lot of trial and error I was able to come up with a fairly elegant solution.

My Training model that I was using to populate a grid has roughly 10 properties and 4 navigation properties used by OpenAccess.  I need to traverse to 2 of the navigation properties in order to display the foreign key descriptions.  After a unsuccessfully attempting to serialize my model using JSON.Net I thought of a better way.

The first thing I did was create a ViewModel that inherits from my Model.  Then I added the 2 denormalized (aka flattened) properties that I needed for the grid to the ViewModel.  In my Controller method that retrieves the data I implemented AutoMapper to auto populate the ViewModel with the Model properties but the key is ignore the navigation properties so the result looks something like this...

[GridAction]
public ActionResult GetGridData(GridCommand gridCommand)
{
    Mapper.CreateMap<Training, TrainingViewModel>()
        .ForMember(x => x.RepCategoryName, x => x.ResolveUsing(y => y.RepCategory.RepCategoryName))
        .ForMember(x => x.TrainingStatusName, x => x.ResolveUsing(y => y.TrainingStatus.TrainingStatusName))
        .ForMember(x => x.RepCategory, x => x.Ignore())
        .ForMember(x => x.TrainingStatus, x => x.Ignore())
        .ForMember(x => x.AdminUser, x => x.Ignore())
        .ForMember(x => x.User, x => x.Ignore());
     
    var trainings = _DataAccess.Trainings.Where(x => x.User.EmailAddress == User.Identity.Name).ToList();
    var trainingViewModels = Mapper.Map<List<TrainingViewModel>>(trainings);
     
    return View(new GridModel(trainingViewModels));
}

It works great and I only have to set up the mappings once!  An added benefit is that I can still accept the Model as inputs to my insert and delete methods because the properties match up perfectly!
0
Bill
Top achievements
Rank 1
answered on 12 Feb 2012, 12:23 AM
I had a similar issue. I'm using Ajax binding on the grid with the Entity Framework 4. The link below helped me out.

http://blogs.telerik.com/aspnetmvcteam/posts/10-01-25/resolving-circular-references-when-binding-the-mvc-grid.aspx

There are a few options but I chose the one "Zare" used. See the comments to the blog pos regarding anonymous types. The View Model approach is probably the most sound solution however.
Tags
Grid
Asked by
oliwa
Top achievements
Rank 1
Answers by
Daniel
Telerik team
oliwa
Top achievements
Rank 1
Bill
Top achievements
Rank 1
Share this question
or