我尝试序列化从实体数据模型.edmx自动生成的POCO类,当我使用
JsonConvert.SerializeObject
我得到了以下错误:
为System.data.entity类型检测到自我引用循环错误。
我怎么解决这个问题?
我尝试序列化从实体数据模型.edmx自动生成的POCO类,当我使用
JsonConvert.SerializeObject
我得到了以下错误:
为System.data.entity类型检测到自我引用循环错误。
我怎么解决这个问题?
当前回答
c#代码:
var jsonSerializerSettings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
};
var jsonString = JsonConvert.SerializeObject(object2Serialize, jsonSerializerSettings);
var filePath = @"E:\json.json";
File.WriteAllText(filePath, jsonString);
其他回答
对我来说,我必须走不同的路线。而不是试图修复JSON。我必须在我的数据上下文的惰性加载之后。
我刚刚添加了这个到我的基本库:
context.Configuration.ProxyCreationEnabled = false;
“context”对象是我在基本存储库中使用的构造函数参数,因为我使用依赖注入。您可以在实例化数据上下文的任何地方更改ProxyCreationEnabled属性。
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
要在MVC 6中忽略循环引用并且不全局序列化它们,请在startup.cs中使用以下命令:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().Configure<MvcOptions>(options =>
{
options.OutputFormatters.RemoveTypesOf<JsonOutputFormatter>();
var jsonOutputFormatter = new JsonOutputFormatter();
jsonOutputFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
options.OutputFormatters.Insert(0, jsonOutputFormatter);
});
}
团队:
这适用于ASP。核心网;上面的挑战是如何“设置为忽略”。根据您设置应用程序的方式,这可能相当具有挑战性。以下是对我有效的方法。
这可以放在你的公共void ConfigureServices(IServiceCollection services)部分。
services.AddMvc().AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
我们可以将这两行添加到DbContext类构造函数中以禁用Self引用循环,例如
public TestContext()
: base("name=TestContext")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
最好的解决方案是从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.