我使用的是AngularJS,EF和WebAPI。我在ObjectA和ObjectB之间有一对多的关系。
在UI中,我想循环遍历ObjectA列表并执行以下操作:
<table>
<tr ng-repeat="objectA in objectAs">
<td>objectA.objectB.Description</td>
<td>objectA.someValue</td>
</tr>
</table>
问题是,如果在我的访问层中,我会这样做:
db.ObjectA.Include(o => o.ObjectB).ToList()
我收到一个很好的错误:
Object graph for type 'ObjectB' contains cycles and cannot be serialized if reference tracking is disabled.
好的,没问题,我只想补充一下:
[DataContract(IsReference =真)]
生成合同的* .tt文件(来自EF)。
WebAPI返回有效值(无错误),但看起来Angluar无法处理&#34;引用&#34;返回,看起来像:
[ { &#34; $ id&#34;:&#34; 1&#34;, &#34; someValue&#34;:&#34; Pool&#34;, &#34; objectB&#34;:{ &#34; $ id&#34;:&#34; 2&#34;, &#34;描述&#34;:&#34;标准&#34;, &#34; ObjectAs&#34;:[ { &#34; $ ref&#34;:&#34; 1&#34; }, { &#34; $ id&#34;:&#34; 3&#34;, &#34; someValue&#34;:&#34; Poolhouse&#34;, &#34; ObjectB&#34;:{ &#34; $ ref&#34;:&#34; 2&#34; }, }, }, { &#34; $ ref&#34;:&#34; 3&#34; }, { &#34; $ ref&#34;:&#34; 4&#34; }, { &#34; $ ref&#34;:&#34; 5&#34; }, { &#34; $ ref&#34;:&#34; 6&#34; }, { &#34; $ ref&#34;:&#34; 7&#34; }, { &#34; $ ref&#34;:&#34; 8&#34; }, { &#34; $ ref&#34;:&#34; 9&#34; }, { &#34; $ ref&#34;:&#34; 10&#34; }, { &#34; $ ref&#34;:&#34; 11&#34; } ]
现在我无法修改我的DTO以删除某些导航属性的DataMember属性。
有关最佳做法的建议吗?我应该只返回一个光DTO(只是对象A),然后有一个查找对象B的javascript方法吗?
修改
我看了一下Angular的输出。事实证明它将WebAPI放入的$ ref道具转换为空元素{}。有点像...
[
{
"$id": "1",
"someValue": "Pool",
"objectB": {
"$id": "2",
"Description": "Standard",
"ObjectAs": [
{
},
{
"$id": "3",
"someValue": "Poolhouse",
"ObjectB": {
},
},
},
{}, {},{}, {},{}, {},{}, {}
]
所以从这里开始,我看到了一些选择:
将代码更改为仅返回单个对象并进行sep调用以获取查找字段
将代码设置为空循环引用:
ObjectA.objectB.ObjectAs = null;
我原本预计这是一个常见的问题,但似乎找不到任何关于它的帖子。还有其他人遇到这个吗?
答案 0 :(得分:4)
我最后将其添加到WebApiConfig:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
从WebApi(没有引用)
产生“更好”的json