如何在Newtonsoft JSON序列化程序中禁用对象引用创建?

use*_*100 11 c# asp.net json json.net

我将我的ASP.NET MVC应用程序切换为使用Newtonsoft JsonSerializer来执行我们的JSON序列化,如下所示:

var writer = new JsonTextWriter(HttpContext.Response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create();
serializer.Serialize(writer, myData);
Run Code Online (Sandbox Code Playgroud)

这会生成一些具有$ id和$ ref属性的JSON,然后从JSON中删除重复的对象.我知道这是一个很棒的功能,但是阅读这个JSON的客户端不能支持解释这些引用并期望完整的对象存在.我已经尝试将PreserveReferencesHandling属性设置JsonSerializerSettings为每个可能的值,它似乎没有任何区别.

如何禁用$ id和$ ref属性的创建,并让Newtonsoft序列化器写出整个对象图?

编辑:这是一个示例C#类,我期望的JSON,以及由Newtonsoft序列化程序创建的JSON:

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

我希望JSON:

{
    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' }]
}
Run Code Online (Sandbox Code Playgroud)

由Newtonsoft序列化程序创建的JSON(注意MainImage中添加的$ id参数,引用的对象完全被$ ref参数替换):

{
    MainImage: { $id: 1, Id: 1, Url: 'http://contoso.com/product.png' },
    AllImages: [{ $ref: 1 },{ Id: 2, Url: 'http://contoso.com/product2.png' }]
}
Run Code Online (Sandbox Code Playgroud)

我知道Newtonsoft版本更好(它是DRYer)但是读取此JSON输出的客户端不理解$ ref的含义.

Bri*_*ers 24

我从你的评论中看到你的课程实际上是用它来装饰的[DataContract(IsReference = true)],这就解释了为什么你看到你的JSON中添加了参考信息.从序列化属性JSON.Net文档:

除了使用内置的Json.NET属性之外,Json.NET还会在确定如何序列化和反序列化JSON时查找SerializableAttribute(如果DefaultContractResolver上的IgnoreSerializableAttribute设置为false)DataContractAttribute,DataMemberAttributeNonSerializedAttribute ....

它还说:

注意

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

所以,似乎你的问题的解决方案很简单:只需[JsonObject(IsReference = false)]像这样添加到你的类:

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

这将允许您保留WCF属性,但在序列化为JSON时将覆盖引用行为.

  • 所以,我相信我弄明白了.在独立项目中,此代码的工作方式与您描述的一样.但是,我正在使用的对象使用`[DataContract(IsReference = true)]`属性进行修饰,因为它们也用于WCF服务层.我没想到Newtonsoft JSON序列化程序实际上会查看WCF属性,但我想它确实如此,即使`PreserveReferencesHandling`设置为None.知道如何禁用它吗? (2认同)