我尝试序列化从实体数据模型.edmx自动生成的POCO类,当我使用
JsonConvert.SerializeObject
我得到了以下错误:
为System.data.entity类型检测到自我引用循环错误。
我怎么解决这个问题?
我尝试序列化从实体数据模型.edmx自动生成的POCO类,当我使用
JsonConvert.SerializeObject
我得到了以下错误:
为System.data.entity类型检测到自我引用循环错误。
我怎么解决这个问题?
当前回答
最简单的方法是安装Json。网 从nuget中添加[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; }
尽管这些天,我创建了一个只包含我想要传递的属性的模型,所以它更轻,不包括不需要的集合,并且当我重新构建生成的文件时,我不会丢失我的更改……
其他回答
最好的解决方案是从Web API中的循环引用处理(这个答案的大部分都是从这里复制的):
修复1:全局忽略循环引用
(我已经选择/尝试了这一个,就像其他许多人一样)
The json.net serializer has an option to ignore circular references. Put the following code in WebApiConfig.cs file: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; The simple fix will make serializer to ignore the reference which will cause a loop. However, it has limitations: The data loses the looping reference information The fix only applies to JSON.net The level of references can't be controlled if there is a deep reference chain
如果你想在非api的ASP中使用这个修复。NET项目,你可以添加上述行到Global.asax.cs,但首先添加:
var config = GlobalConfiguration.Configuration;
如果你想在.Net Core项目中使用它,你可以将Startup.cs更改为:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Fix 2: Preserving circular reference globally This second fix is similar to the first. Just change the code to: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize; config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; The data shape will be changed after applying this setting. [ { "$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" } ] The $id and $ref keeps the all the references and makes the object graph level flat, but the client code needs to know the shape change to consume the data and it only applies to JSON.NET serializer as well. Fix 3: Ignore and preserve reference attributes This fix is decorate attributes on model class to control the serialization behavior on model or property level. To ignore the property: public class Category { public int Id { get; set; } public string Name { get; set; } [JsonIgnore] [IgnoreDataMember] public virtual ICollection<Product> Products { get; set; } } JsonIgnore is for JSON.NET and IgnoreDataMember is for XmlDCSerializer. To preserve reference: // 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; } } JsonObject(IsReference = true)] is for JSON.NET and [DataContract(IsReference = true)] is for XmlDCSerializer. Note that: after applying DataContract on class, you need to add DataMember to properties that you want to serialize. The attributes can be applied on both json and xml serializer and gives more controls on model class.
对我来说,我必须走不同的路线。而不是试图修复JSON。我必须在我的数据上下文的惰性加载之后。
我刚刚添加了这个到我的基本库:
context.Configuration.ProxyCreationEnabled = false;
“context”对象是我在基本存储库中使用的构造函数参数,因为我使用依赖注入。您可以在实例化数据上下文的任何地方更改ProxyCreationEnabled属性。
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
简单地放置Configuration。ProxyCreationEnabled = false;在上下文文件中;这样问题就解决了。
public demEntities()
: base("name=demEntities")
{
Configuration.ProxyCreationEnabled = false;
}
如果你使用的是。net Core 2。x,更新Startup.cs中的ConfigureServices部分
https://learn.microsoft.com/en-us/ef/core/querying/related-data/serialization
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
如果你使用的是。net Core 3。x - 5.0,没有MVC,它将是:
# startup.cs
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
对于。net 6.0,唯一的不同是它现在进入Program.cs。
# program.cs
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore);
如果你使用实体框架和数据库优先的设计模式,这个引用循环处理几乎是强制性的。
团队:
这适用于ASP。核心网;上面的挑战是如何“设置为忽略”。根据您设置应用程序的方式,这可能相当具有挑战性。以下是对我有效的方法。
这可以放在你的公共void ConfigureServices(IServiceCollection services)部分。
services.AddMvc().AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});