ASP.NET API序列化具有循环依赖关系的实体
本文关键字:依赖 关系 实体 循环 NET API 序列化 ASP | 更新日期: 2023-09-27 18:05:42
我有Test
实体和User
实体。
测试:
public class Test
{
public int Id {get; set;}
public string Title {get; set;}
...
public virtual IList<User> Users {get; set;}
}
用户:
public class User
{
public int Id {get; set;}
public string Name {get; set;}
...
public virtual IList<Test> Tests {get; set;}
}
在我的TestsApiController
中,我有以下操作:
public IQueryable<Test> GetTests()
{
return db.Tests;
}
这会返回一个序列化异常,因为它试图循环序列化User
对象、Test
对象和User
对象,依此类推
我目前的计划是创建一个包含IList<int> UserIds
而不是实际对象的TestDTO
。然后,在序列化之前,我必须将所有Test
对象转换为TestDTO
对象,这有点烦人。然后,如果我想序列化具有循环依赖关系的其他实体,我必须为它们创建更多的数据传输对象。
有没有一种方法可以创建或配置序列化程序来自动将上下文中的User
(或任何其他(对象序列化为简单的Id
属性?
例外编辑:无论使用XML
还是JSON
,我都会得到相同的异常
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.DynamicProxies.Test_6585C5F85A384907958ABA03B661933EF718BDEDE1513392E060DE06E80DB552' with data contract name 'Test_6585C5F85A384907958ABA03B661933EF718BDEDE1513392E060DE06E80DB552:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>...</StackTrace>
</InnerException>
</Error>
构造json结果的一种非常简单的方法是使用NewtonSoft json序列化程序中的JObject(这通常是ASP.NET Web Api中的默认值(。你要找的东西看起来像
public JObject GetTests()
{
NewtonSoft.Json.Linq.JObject jsonResult = NewtonSoft.Json.Linq.JObject.FromObject(new
{
Tests = from test in db.tests
select new
{
Id = test.Id,
Title = test.Title,
Users = from user in test.Users
select new
{
Id = user.Id
}
}
});
return jsonResult;
}
这使您能够更好地控制json结果,这样您就可以选择要序列化的字段/属性,从而避免创建大量的数据传输对象。希望这能有所帮助。
干杯
在web api配置(App_Start/WebApiConfig.cs(中,添加以下内容:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Prevent "Self referencing loop detected" error occurring for recursive objects
var serializerSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
config.Formatters.JsonFormatter.SerializerSettings = serializerSettings;
}
}
此操作会告诉JSON.NET忽略引用回父对象的嵌套对象