17

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?

2
  • Setting this in the WebApiConfig class (public static void Register (HttpConfiguration config) called from the protected void Application_Start () within Global.asax.cs Commented Jan 10, 2014 at 20:18
  • 1
    As per @AndreHaverdings' answer below, having PreserveReferencesHandling set to All causes the ids and references to be added. Setting your last line to jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; should do the trick. Commented Jun 9, 2014 at 16:28

5 Answers 5

26

Put this in the Global.asax to configure reference handling. PreserveReferencesHandling should not be 'All'

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
Sign up to request clarification or add additional context in comments.

2 Comments

I've tried all combinations of PreserveReferencesHandling, including "None." Every settings (currently "None") results in the same output: $id/$ref being output. Something, somewhere must be overriding my setting.
@Michael could you fix this error? Can you please help me on this topic : stackoverflow.com/questions/41244296/…
7

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

7

Here is some javascript I'm using to handle the $id/$ref objects on the client side:

// function to return a JSON object form a JSON.NET serialized object with $id/$ref key-values
// obj: the obj of interest.
// parentObj: the top level object containing all child objects as serialized by JSON.NET.
function getJsonNetObject(obj, parentObj) {
    // check if obj has $id key.
    var objId = obj["$id"];
    if (typeof (objId) !== "undefined" && objId != null) {
        // $id key exists, so you have the actual object... return it
        return obj;
    }
    // $id did not exist, so check if $ref key exists.
    objId = obj["$ref"];
    if (typeof (objId) !== "undefined" && objId != null) {
        // $ref exists, we need to get the actual object by searching the parent object for $id
        return getJsonNetObjectById(parentObj, objId);
    }
    // $id and $ref did not exist... return null
    return null;
}

// function to return a JSON object by $id
// parentObj: the top level object containing all child objects as serialized by JSON.NET.
// id: the $id value of interest
function getJsonNetObjectById(parentObj, id) {
    // check if $id key exists.
    var objId = parentObj["$id"];
    if (typeof (objId) !== "undefined" && objId != null && objId == id) {
        // $id key exists, and the id matches the id of interest, so you have the object... return it
        return parentObj;
    }
    for (var i in parentObj) {
        if (typeof (parentObj[i]) == "object" && parentObj[i] != null) {
            //going one step down in the object tree
            var result = getJsonNetObjectById(parentObj[i], id);
            if (result != null) {
                // return found object
                return result;
            }
        }
    }
    return null;
}

1 Comment

Thanks for an answer that actually works. I spent the last half hour trying to turn this off in Microsoft WebApi 2.1
0

My application was causing error i debugged my asp.net application till it gave me the collection of model causing this issue. just placed the [JsonIgnore] tag and it worked fine.

[JsonIgnore]
public virtual ICollection<customer_details> customer_details { get; set; }

You can manually test by assigning [JsonIgnore] to all ICollection in Model to discover the source of issue.

Comments

-2

[JsonIgnore] worked for me. Within the model, include:

    [JsonIgnore] 
    public virtual ICollection<cell_order> cell_order { get; set; }

Unfortunately, this must be done for each case where needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.