Json and Circular Reference Exception

前端 未结 9 1392
挽巷
挽巷 2020-11-27 03:17

I have an object which has a circular reference to another object. Given the relationship between these objects this is the right design.

To Illustrate

相关标签:
9条回答
  • 2020-11-27 04:13

    Update:

    Do not try to use NonSerializedAttribute, as the JavaScriptSerializer apparently ignores it.

    Instead, use the ScriptIgnoreAttribute in System.Web.Script.Serialization.

    public class Machine
    {
        public string Customer { get; set; }
    
        // Other members
        // ...
    }
    
    public class Customer
    {
        [ScriptIgnore]
        public Machine Machine { get; set; }    // Parent reference?
    
        // Other members
        // ...
    }
    

    This way, when you toss a Machine into the Json method, it will traverse the relationship from Machine to Customer but will not try to go back from Customer to Machine.

    The relationship is still there for your code to do as it pleases with, but the JavaScriptSerializer (used by the Json method) will ignore it.

    0 讨论(0)
  • 2020-11-27 04:13

    I'm answering this despite its age because it is the 3rd result (currently) from Google for "json.encode circular reference" and although I don't agree with the answers (completely) above, in that using the ScriptIgnoreAttribute assumes that you won't anywhere in your code want to traverse the relationship in the other direction for some JSON. I don't believe in locking down your model because of one use case.

    It did inspire me to use this simple solution.

    Since you're working in a View in MVC, you have the Model and you want to simply assign the Model to the ViewData.Model within your controller, go ahead and use a LINQ query within your View to flatten the data nicely removing the offending circular reference for the particular JSON you want like this:

    var jsonMachines = from m in machineForm
                       select new { m.X, m.Y, // other Machine properties you desire
                                    Customer = new { m.Customer.Id, m.Customer.Name, // other Customer properties you desire
                                  }};
    return Json(jsonMachines);
    

    Or if the Machine -> Customer relationship is 1..* -> * then try:

    var jsonMachines = from m in machineForm
                       select new { m.X, m.Y, // other machine properties you desire
                                    Customers = new List<Customer>(
                                                   (from c in m.Customers
                                                    select new Customer()
                                                    {
                                                       Id = c.Id,
                                                       Name = c.Name,
                                                       // Other Customer properties you desire
                                                    }).Cast<Customer>())
                                   };
    return Json(jsonMachines);
    
    0 讨论(0)
  • 2020-11-27 04:14

    Since, to my knowledge, you cannot serialize object references, but only copies you could try employing a bit of a dirty hack that goes something like this:

    1. Customer should serialize its Machine reference as the machine's id
    2. When you deserialize the json code you can then run a simple function on top of it that transforms those id's into proper references.
    0 讨论(0)
提交回复
热议问题