Is there a JavaScript (client-side) JSON library that integrates well with JSON.NET (server-side) and supports the "preserve references" feature?
Asked Answered
G

2

8

JSON.NET supports circular reference serialization by preserving all references with the following settings:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
settings.PreserveReferencesHandling = PreserveReferencesHandling.All;

That allows the following code to run without errors, properly serializing and deserializing the object with its self-reference intact.

public class SelfReferencingClass
{
    public string Name;
    public SelfReferencingClass Self;
    public SelfReferencingClass() {Name="Default"; Self=this;}
}

SelfReferencingClass s = new SelfReferencingClass();
string jsondata = JsonConvert.SerializeObject( d, settings );
s = JsonConvert.DeserializeObject<SelfReferencingClass>( jsondata, settings );

The jsondata string looks like this:

{"$id":"1","Name":"Default","Self":{"$ref":"1"}}

The problem is... how is this feature of JSON.NET useful at all without a corresponding client side JavaScript library that can interpret these references, and also support encoding such references itself?

What client-side library (e.g. JSON.stringify) supports this feature/encoding using "$id" and "$ref" fields? If none exist, is there a known way to add support to an existing library?

Adding support myself would be a pretty straightforward two-pass process. First, deserialize the entire string, and as you create each object add it to a dictionary using its "$id" value as the key. When you encounter references (object consisting of just a "$ref" property) you could add it to a list of object+fieldname that you could go back over to replace each encountered reference by looking up its key in the final dictionary of created objects.

Guanajuato answered 5/8, 2013 at 19:10 Comment(3)
I've looked everywhere for a solution. There seems to be something called "dojo" (sitepen.com/blog/2008/06/17/json-referencing-in-dojo) that has this kind of support too, but it's also server-side and it doesn't seem to include the "$" in the id field, so it's not even consistent with the way JSON.NET handles reference encoding.Guanajuato
The JSON 3 serializer bestiejs.github.io/json3 also lacks cyclic reference support and will throw an error. Code comment is '// Cyclic structures cannot be serialized by JSON.stringify.'Guanajuato
this question contains the answer: #13782552Novokuznetsk
T
2

There are few options:

  1. Douglas Crockford's original JSON library has plugin called cycle.js that resolved circular references. Also see this answer which has enhanced version of method to resolve references: Resolve circular references from JSON object.
  2. Cereal which handles circular references and object graphs better.
  3. CircularJSON which is very small and does exactly what it says.

Having said that, I would probably refactor my design to avoid circular references because JSON is usually core component and you probably want to use mainstream libraries which is very well tested and supported. One way to avoid circular references is just to create lightweight shim objects and serialize them instead. Alternatively implement custom interface (if you have access to class) that overrides serialization behavior. You can probably even automate it using reflection to avoid properties with circular references.

Tolkan answered 7/3, 2014 at 8:31 Comment(0)
C
0

@ungap/structured-clone does the job pretty well and it’s standard-compliant.

Cruciate answered 29/11, 2022 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.