circular reference while serializing json

2 posts, 0 answers
  1. Richard
    Richard avatar
    2 posts
    Member since:
    Nov 2012

    Posted 08 Aug 2013 Link to this post

     I have a problem, as the following

    Using sample: "Sofia Car Rental ASP.NET Ajax integration example with OpenAccess"

                SofiaCarRental.DAL.SofiaCarRentalContext context = new SofiaCarRental.DAL.SofiaCarRentalContext();
                List<SofiaCarRental.DAL.Category> ls = context.Categories.ToList();
                System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.SerializationJavaScriptSerializer();
                string output = jss.Serialize(ls);

    // Exception 

    Circular reference was detected while serializing an object of type 'SofiaCarRental.DAL.Category'.

     It solves disabling "Target end" a the Category. How do I set the model from the beginning, in the creation of rlinq





  2. Dimitar Tachev
    Admin
    Dimitar Tachev avatar
    67 posts

    Posted 13 Aug 2013 Link to this post

    Hi Richard,

     
    Removing one of the ends of the associations between the problematic entities is a possible solution for this problem but its disadvantage is that you are loosing a lot of references between the domain classes of your model.

    In order to convert the Categories from you context instance to their JSON string representation I suggest you the following approach using the JSON.NET library which could also be downloaded as a Nuget package:

    string jsonData = string.Empty;
     
    // get JSON string from the categories
    using (EntitiesModel context = new EntitiesModel())
    {
        // specify the fetch plan for the detaching
        FetchStrategy fetchStrategy = new FetchStrategy();
        fetchStrategy.LoadWith<Category>(c => c.Products);
        fetchStrategy.LoadWith<Product>(p => p.OrderDetails);
     
        // detach the categories with their products and the order details
          //along with the products (without the opposite references)
        IList<Category> categories = context.Categories.ToList();
        var detachedCategories =
    context.CreateDetachedCopy<Category>(categories, fetchStrategy);
     
        // avoid getting error for possible circular references
        JsonSerializerSettings serializationSettings = new JsonSerializerSettings()
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
     
        // convert the detached categories along with their products
          // and OrderDetails to JSON string
        jsonData =
    JsonConvert.SerializeObject(detachedCategories, serializationSettings);
    }
     
    // ....
    // pass the JSON string to the client for some CRUD
    // operations and return a JSON string again
    // ....
     
    // attach the categories from the JSON string
    using (EntitiesModel context = new EntitiesModel())
    {
        // convert the JSON string to list of Category objects
          // along with the Products and their OrderDetails
        List<Category> deserializedCategories = JsonConvert.DeserializeObject<List<Category>>(jsonData);
     
        foreach (Category category in deserializedCategories)
        {
            // attach each of the categories to a context instance (the context
       // can be the same or different from the previous one)
            // in order to track the changes and resolve again all
       //of the references from the objects graph
            context.AttachCopy<Category>(category);
        }
     
        // commit the changes from the JSON string to the database
        context.SaveChanges();
    }

    Choosing this approach you will not need to remove some ends of your associations because you could specify only the navigation properties that you need in the FetchPlan and disable the loop handling validation of the JSON.NET converter.

    If this is not applicable for you and you want to use the JavaScriptSerializer I believe that you will need to manually remove the problematic association ends - there isn't a global setting for removing one of the ends.

    I hope this helps. Do not hesitate to contact us back if you need any further assistance.


    Regards,
    Dimitar Tachev
    Telerik
    OpenAccess ORM Q2 2013 brings you a more powerful code generation and a unique Bulk Operations support with LINQ syntax. Check out the list of new functionality and improvementsshipped with this release.

  3. DevCraft banner
Back to Top