Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Newtonsoft JSON序列化程序中禁用对象引用创建?_C#_Asp.net_Json_Json.net - Fatal编程技术网

C# 如何在Newtonsoft 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

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

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