C# 如何在Newtonsoft JSON序列化程序中禁用对象引用创建?
我将我的ASP.NET MVC应用程序切换为使用Newtonsoft JsonSerializer进行JSON序列化,如下所示:C# 如何在Newtonsoft JSON序列化程序中禁用对象引用创建?,c#,asp.net,json,json.net,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); 这将生成一些具有$id和$r
var writer = new JsonTextWriter(HttpContext.Response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create();
serializer.Serialize(writer, myData);
这将生成一些具有$id和$ref属性的JSON,然后从JSON中删除重复的对象。我知道这是一个很好的特性,但是读取此JSON的客户机不支持解释这些引用,并且希望有完整的对象。我已尝试将JsonSerializerSettings
上的preserverencesshandling
属性设置为所有可能的值,但似乎没有任何区别
如何禁用$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; }
}
由Newtonsoft序列化程序创建的JSON(请注意,在MainImage中添加了$id参数,并且引用的对象被$ref参数完全替换):
我知道Newtonsoft版本更好(更干燥),但读取此JSON输出的客户端不理解$ref的含义。我从您的评论中看到,您的类实际上是用
[DataContract(IsReference=true)]
修饰的,因此,这就解释了为什么您会看到引用信息被添加到JSON中。从:
除了使用内置的Json.NET属性外,Json.NET还查找(如果DefaultContractResolver上的IgnoreSerializableAttribute设置为false),并且。。。确定如何序列化和反序列化JSON时
它还说:
注意
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; }
}
[DataContract(IsReference=true)]
[JsonObject(IsReference=false)]
公共类产品
{
[数据成员]
公共映像主映像{get;set;}
[数据成员]
公共列表所有图像{get;set;}
}
[DataContract(IsReference=true)]
[JsonObject(IsReference=false)]
公众阶级形象
{
[数据成员]
公共int Id{get;set;}
[数据成员]
公共字符串Url{get;set;}
}
这将允许您保留WCF属性,但在序列化为JSON时将覆盖引用行为。如果您发布了一些代表您试图序列化的内容的示例数据,这将非常有用,以及所需的JSON输出。@BrianRogers我已经编辑过,包括示例代码和数据。您使用的是哪个Newtonsoft版本?因为在一个5.0.6版本的空项目中,没有$id和$ref,我得到了您的预期结果…所以,我相信我已经找到了答案。在独立项目中,此代码的工作方式与您描述的相同。但是,我使用的对象用
[DataContract(IsReference=true)]
属性修饰,因为它们也在WCF服务层中使用。我并不期望Newtonsoft JSON序列化程序实际查看WCF属性,但我猜它确实会查看,即使PreserveReferencesHandling
设置为None。你知道如何禁用它吗?我做了与你写的完全相同的事情,我有带有[DataContract(IsReference=true)]
和[JsonObject(IsReference=false)]
的wcf,但仍然使用$id
祝你万岁,先生
{
MainImage: { $id: 1, Id: 1, Url: 'http://contoso.com/product.png' },
AllImages: [{ $ref: 1 },{ Id: 2, Url: 'http://contoso.com/product2.png' }]
}
[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; }
}