Michael Michael - 1 month ago 15
C# Question

Prevent $id/$ref when serializing objects using Web API and JSON.NET

I can't seem to prevent Web API/JSON.NET from using

Newtonsoft.Json.PreserveReferencesHandling.Objects
when serializing objects. In other words, $id/$ref are always used in the serialized objects despite using the following settings:

public class MvcApplication : System.Web.HttpApplication {

protected void Application_Start () {
WebApiConfig.Register(GlobalConfiguration.Configuration);
}

}

public static class WebApiConfig {

public static void Register (HttpConfiguration config) {
JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().Single();
jsonFormatter.UseDataContractJsonSerializer = false;
jsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
jsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
}

}


Any ideas?

Answer

If using serialization attributes on your objects (such as DataContract), 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][2] (if IgnoreSerializableAttribute on DefaultContractResolver is set to false) [DataContractAttribute][3], [DataMemberAttribute][4] and [NonSerializedAttribute][5] ... when determining how JSON is to be serialized and deserialized.

It also says this:

Note

Json.NET attributes take presidence 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.

It seems the solution to the problem is to add [JsonObject(IsReference = false)] to your object(s) like this:

[DataContract(IsReference = true)]
[JsonObject(IsReference = false)]
public class MyObject
{
    [DataMember]
    public int MyProperty { get; set; }
}
Comments