Nev*_*ynh 458 serialization json json.net
我试图序列化从实体数据模型.edmx自动生成的POCO类,当我使用时
JsonConvert.SerializeObject
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
错误发生类型System.data.entity检测到的自引用循环.
我该如何解决这个问题?
Dal*_*oft 446
使用JsonSerializerSettings
ReferenceLoopHandling.Error如果遇到引用循环,则(默认)将出错.这就是你得到例外的原因.ReferenceLoopHandling.Serialize 如果对象嵌套但不是无限期,则非常有用.ReferenceLoopHandling.Ignore 如果对象是自身的子对象,则不会序列化对象. 例:
JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
});
Run Code Online (Sandbox Code Playgroud)
如果必须序列化无限期嵌套的对象,可以使用PreserveObjectReferences来避免StackOverflowException.
例:
JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented,
new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
Run Code Online (Sandbox Code Playgroud)
选择对序列化对象有意义的内容.
参考http://james.newtonking.com/json/help/
Bis*_*nna 441
这是最好的解决方案 https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7
(我和其他许多人一样选择/试过这个)
json.net序列化程序有一个忽略循环引用的选项.将以下代码放在WebApiConfig.cs文件中:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
Run Code Online (Sandbox Code Playgroud)
简单的修复将使序列化程序忽略将导致循环的引用.但是,它有局限性:
数据丢失循环引用信息修复仅适用于JSON.net如果存在深度引用链,则无法控制引用级别
如果要在非api ASP.NET项目中使用此修补程序,可以将上面的行添加到Global.asax.cs,但首先添加:
var config = GlobalConfiguration.Configuration;
Run Code Online (Sandbox Code Playgroud)
如果要在.Net Core项目中使用它,可以更改Startup.cs为:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Run Code Online (Sandbox Code Playgroud)
第二个修复与第一个类似.只需将代码更改为:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;
Run Code Online (Sandbox Code Playgroud)
应用此设置后,将更改数据形状.
[
{
"$id":"1",
"Category":{
"$id":"2",
"Products":[
{
"$id":"3",
"Category":{
"$ref":"2"
},
"Id":2,
"Name":"Yogurt"
},
{
"$ref":"1"
}
],
"Id":1,
"Name":"Diary"
},
"Id":1,
"Name":"Whole Milk"
},
{
"$ref":"3"
}
]
Run Code Online (Sandbox Code Playgroud)
$ id和$ ref保留所有引用并使对象图层保持平坦,但客户端代码需要知道形状更改才能使用数据,它也只适用于JSON.NET序列化程序.
此修复是模型类上的decorate属性,用于控制模型或属性级别上的序列化行为.要忽略该属性:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
[IgnoreDataMember]
public virtual ICollection<Product> Products { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
JsonIgnore用于JSON.NET,IgnoreDataMember用于XmlDCSerializer.保留参考:
// Fix 3
[JsonObject(IsReference = true)]
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
// Fix 3
//[JsonIgnore]
//[IgnoreDataMember]
public virtual ICollection<Product> Products { get; set; }
}
[DataContract(IsReference = true)]
public class Product
{
[Key]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public virtual Category Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
JsonObject(IsReference = true)]适用于JSON.NET,[DataContract(IsReference = true)]适用于XmlDCSerializer.请注意:在应用于DataContract类之后,您需要添加DataMember要序列化的属性.
这些属性可以应用于json和xml序列化程序,并对模型类提供更多控制.
smo*_*kle 49
修复是忽略循环引用而不是序列化它们.此行为在JsonSerializerSettings.中指定.
单人JsonConvert过载:
JsonConvert.SerializeObject(YourObject, Formatting.Indented,
new JsonSerializerSettings() {
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
}
);
Run Code Online (Sandbox Code Playgroud)
Application_Start()Global.asax.cs中代码的全局设置:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
Formatting = Newtonsoft.Json.Formatting.Indented,
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};
Run Code Online (Sandbox Code Playgroud)
参考:https://github.com/JamesNK/Newtonsoft.Json/issues/78
Sam*_*nes 44
最简单的方法是从nuget 安装Json.NET
并将该[JsonIgnore]属性添加到类中的虚拟属性,例如:
public string Name { get; set; }
public string Description { get; set; }
public Nullable<int> Project_ID { get; set; }
[JsonIgnore]
public virtual Project Project { get; set; }
Run Code Online (Sandbox Code Playgroud)
虽然现在,我创建了一个只有我想要传递的属性的模型,因此它更轻,不包含不需要的集合,并且在重建生成的文件时我不会丢失我的更改...
Cal*_*leb 21
在.NET Core 1.0中,您可以将其设置为Startup.cs文件中的全局设置:
using System.Buffers;
using Microsoft.AspNetCore.Mvc.Formatters;
using Newtonsoft.Json;
// beginning of Startup class
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.OutputFormatters.Clear();
options.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings(){
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}, ArrayPool<char>.Shared));
});
}
Run Code Online (Sandbox Code Playgroud)
小智 8
我们可以将这两行添加到DbContext类构造函数中以禁用自引用循环,就像
public TestContext()
: base("name=TestContext")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
Run Code Online (Sandbox Code Playgroud)
在发生循环问题时,要在NEWTONSOFTJSON中序列化我们,就我而言,我不需要修改global.asax或apiconfig。我只是使用JsonSerializesSettings忽略了循环处理。
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var lst = db.shCards.Where(m => m.CardID == id).ToList();
string json = JsonConvert.SerializeObject(lst, jss);
Run Code Online (Sandbox Code Playgroud)
如果您使用的是.NET Core 2.x,请更新Startup.cs中的ConfigureServices部分
https://docs.microsoft.com/zh-cn/ef/core/querying/related-data#related-data-and-serialization
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Entity Framework和数据库优先设计模式,那么这几乎是强制性的。
您也可以将属性应用于属性。该[JsonProperty( ReferenceLoopHandling = ... )]属性非常适合于此。
例如:
/// <summary>
/// Represents the exception information of an event
/// </summary>
public class ExceptionInfo
{
// ...code omitted for brevity...
/// <summary>
/// An inner (nested) error.
/// </summary>
[JsonProperty( ReferenceLoopHandling = ReferenceLoopHandling.Ignore, IsReference = true )]
public ExceptionInfo Inner { get; set; }
// ...code omitted for brevity...
}
Run Code Online (Sandbox Code Playgroud)
希望有帮助,Jaans
| 归档时间: |
|
| 查看次数: |
269609 次 |
| 最近记录: |