Json and Circular Reference Exception

Viewed 38708

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

Machine => Customer => Machine

As is expected I run into an issue when I try to use Json to serialize a machine or customer object. What I am unsure of is how to resolve this issue as I don't want to break the relationship between the Machine and Customer objects. What are the options for resolving this issue?

Edit

Presently I am using Json method provided by the Controller base class. So the serialization I am doing is as basic as:

Json(machineForm);
9 Answers

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.

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.

You need to decide which is the "root" object. Say the machine is the root, then the customer is a sub-object of machine. When you serialise machine, it will serialise the customer as a sub-object in the JSON, and when the customer is serialised, it will NOT serialise it's back-reference to the machine. When your code deserialises the machine, it will deserialise the machine's customer sub-object and reinstate the back-reference from the customer to the machine.

Most serialisation libraries provide some kind of hook to modify how deserialisation is performed for each class. You'd need to use that hook to modify deserialisation for the machine class to reinstate the backreference in the machine's customer. Exactly what that hook is depends on the JSON library you are using.

Related