使用Web API和JSON.NET序列化对象时,防止$ id/$ ref

Mic*_*ael 15 c# json.net asp.net-mvc-4 asp.net-web-api

Newtonsoft.Json.PreserveReferencesHandling.Objects在序列化对象时,我似乎无法阻止Web API/JSON.NET的使用.换句话说,尽管使用了以下设置,但$ id/$ ref总是在序列化对象中使用:

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

And*_*ngs 24

将其放在Global.asax中以配置引用处理.PreserveReferencesHandling不应该是'All'

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 7

这里有一些javascript我用来处理客户端的$ id/$ ref对象:

// 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;
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 5

如果在对象上使用序列化属性(例如DataContract),请参阅序列化属性上JSON.Net文档:

除了使用内置的Json.NET属性外,Json.NET还会查找[SerializableAttribute] [2](如果DefaultContractResolver上的IgnoreSerializableAttribute设置为false)[DataContractAttribute] [3],[DataMemberAttribute] [4]和[NonSerializedAttribute] [5] ...确定如何序列化和反序列化JSON.

它还说:

注意

Json.NET属性主要使用标准.NET序列化属性,例如,如果属性上存在JsonPropertyAttribute和DataMemberAttribute,并且都自定义名称,则将使用JsonPropertyAttribute中的名称.

似乎问题的解决方案是添加[JsonObject(IsReference = false)]到您的对象,如下所示:

[DataContract(IsReference = true)]
[JsonObject(IsReference = false)]
public class MyObject
{
    [DataMember]
    public int MyProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)