I switched my ASP.NET MVC application to use the Newtonsoft JsonSerializer to do our JSON serialization, as such:
var writer = new JsonTextWriter(HttpContext.Response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create();
serializer.Serialize(writer, myData);
This generates some JSON that has $id and $ref properties and then removes duplicate objects from the JSON. I know it's a feature that is great, but the clients that read this JSON cannot support interpreting these references and expect full objects to be there. I've tried setting the PreserveReferencesHandling
property on the JsonSerializerSettings
to every possible value and it doesn't seem to make any difference.
How can I disable the creation of the $id and $ref properties and get the Newtonsoft serializer to write out the whole object graph?
EDIT: here is a sample C# class, the JSON I expect, and the JSON created by the Newtonsoft serializer:
public class Product
{
public Image MainImage { get; set; }
public List<Image> AllImages { get; set; }
}
public class Image
{
public int Id { get; set; }
public string Url { get; set; }
}
JSON I expect:
{
MainImage: { Id: 1, Url: 'http://contoso.com/product.png' },
AllImages: [{ Id: 1, Url: 'http://contoso.com/product.png' },{ Id: 2, Url: 'http://contoso.com/product2.png' }]
}
JSON created by the Newtonsoft serializer (note the added $id parameter in MainImage and the referenced object being completely replaced by a $ref parameter):
{
MainImage: { $id: 1, Id: 1, Url: 'http://contoso.com/product.png' },
AllImages: [{ $ref: 1 },{ Id: 2, Url: 'http://contoso.com/product2.png' }]
}
I understand that the Newtonsoft version is better (it's DRYer) but the client that reads this JSON output does not understand what $ref means.
To preserve references and handle circular references, set ReferenceHandler to Preserve. This setting causes the following behavior: On serialize: When writing complex types, the serializer also writes metadata properties ( $id , $values , and $ref ).
The Newtonsoft. Json. Schema namespace provides classes that are used to implement JSON schema. Obsolete.
By default, Newtonsoft. Json does case insensitive property name matching during deserialization whereas System. Text. Json does case sensitive matching (with exception in ASP.Net core where you don't need to do anything to achieve behavior like Newtonsoft.
Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). Serialization is the process of converting the state of an object, that is, the values of its properties, into a form that can be stored or transmitted.
I see from your comments that your classes are actually decorated with [DataContract(IsReference = true)]
, so that explains why you are seeing the reference information getting added to your JSON. From the JSON.Net documentation on Serialization Attributes:
As well as using the built-in Json.NET attributes, Json.NET also looks for the SerializableAttribute (if IgnoreSerializableAttribute on DefaultContractResolver is set to false) DataContractAttribute, DataMemberAttribute and NonSerializedAttribute ... when determining how JSON is to be serialized and deserialized.
It also says this:
Note
Json.NET attributes take precedence over standard .NET serialization attributes, e.g. if both JsonPropertyAttribute and DataMemberAttribute are present on a property and both customize the name, the name from JsonPropertyAttribute will be used.
So, it seems the solution to your problem is simple: just add [JsonObject(IsReference = false)]
to your classes like this:
[DataContract(IsReference = true)]
[JsonObject(IsReference = false)]
public class Product
{
[DataMember]
public Image MainImage { get; set; }
[DataMember]
public List<Image> AllImages { get; set; }
}
[DataContract(IsReference = true)]
[JsonObject(IsReference = false)]
public class Image
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Url { get; set; }
}
This will allow you to keep your WCF attributes in place, but will override the reference behavior when it is time to serialize to JSON.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With