原文地址:http://www.it165.net/pro/html/201210/3932.html

最近开始研究Web API,运气不错第一个测试项目就遇到问题@@-当新增Control时选择[API Controller woth read/write actions, using Entity Framework]然后使用Northwnd数据库,数据表选择Orders,Order_Details,Products.

前端javascript程序代码如下

01.@section scripts{
02.<script type="text/javascript">
03.$(document).ready(function () {
04. 
05.$.getJSON('/api/order/', function (data) {
06.alert(data);
07.})
08..error(function (jqXHR, textStatus, err) {
09.alert('Error: ' + err);
10.});
11.});
12.</script>
13.}

执行后出现错误,查询完整的错误说明为Self referencing loop detected…,也就是循环参考.

这错误讯息好熟悉,突然想起以前开发Silverlight RIA Service好像也有类似情况.经上网查询原因后果不其然,问题是一样的,因为ASP.Net
MVC Web
API预设采用JSON.Net作为输出转换,而预设的情况下JSON.Net会自动一层层解析要输出的对象之属性,也就说这个例子中的输出对象为
Order,其中有个属性为Order_Details,而Order_Details也有个属性参考至Order,所以产生了循环相依问题,导致错误产
生.

这个问题处理方式有三种 www.it165.net

1.最简单的方式就是从Entity
Framework着手,停用LazyLoading与ProxyCreation.因为LazyLoading停用后那么当JSON.Net解析
Order对象时其属性Order_Details会返回null(不会自动加载).所以也就避免了此问题

当然此方式的缺点会导致后续程序存取Entity Object时牺牲了LazyLoading的方便性,需要手动处理此问题.

1.db.Configuration.LazyLoadingEnabled = false;
2.db.Configuration.ProxyCreationEnabled = false;
3. 
4.return db.Orders.AsEnumerable();

2.设定JSON.Net忽略循环参考

透过APP_Start的WebApiConfig.cs,设定
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;

使用这个方式时要注意,它只是忽略循环参考的错误,但实际上还是会自动一层层解析要输出的对象之属性,所以若数据会相依有可能会产生无穷循环.

3.设定JSON.Net避免循环参考

透过APP_Start的WebApiConfig.cs,设定

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;

config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;

这种做法与2的差异在于它会将重复过的对象用一个代表取代,譬如底下JSON格式
1:
[{"$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"}]

所以对于数据而言这种作法还是会自动一层层解析要输出的对象之属性,只是避免输出太大量数据.

4.手动设定避免循环参考

如同3的模式,透过[JsonIgnore] 与[JsonObject(IsReference = true)] 细部设定,可以更精确的设定每个要输出的属性.

缺点是1.设定繁杂. 2.只能通用设定无法例外. 3.因为必须直接或透过 partial class方式设定,故无法将设定与Entity Object class做分离

以上作法实际上都有其优缺点, 并没有一个可以通用的模式, 须看需求而定,这问题与同早期RIA Service的问题相同,但这边提供一种比较通用的模式就是采用方法1+方法2或3.

停用LazyLoading,而使用程序的方式(透过 Include方法)决定那些属性要输出.

ASP.Net MVC-Web API使用Entity Framework时遇到Loop Reference的更多相关文章

  1. [译]ABP框架使用AngularJs,ASP.NET MVC,Web API和EntityFramework构建N层架构的SPA应用程序

    本文转自:http://www.skcode.cn/archives/281 本文演示ABP框架如何使用AngularJs,ASP.NET MVC,Web API 和EntityFramework构建 ...

  2. ABP 教程文档 1-1 手把手引进门之 AngularJs, ASP.NET MVC, Web API 和 EntityFramework(官方教程翻译版 版本3.2.5)含学习资料

    本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 转载请注明出处:http://www.cnblogs.com/yabu007/  谢谢 官方文档分四部分 一. 教程文档 二.ABP 框架 三. ...

  3. Asp.net mvc web api 在项目中的实际应用

    Asp.net mvc web api 在项目中的实际应用 前言:以下只是记录本人在项目中的应用,而web api在数据传输方面有多种实现方式,具体可根据实际情况而定! 1:数据传输前的加密,以下用到 ...

  4. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  5. ASP.NET MVC Web API Post FromBody(Web API 如何正确 Post)

    问题场景: ASP.NET MVC Web API 定义 Post 方法,HttpClient 使用 JsonConvert.SerializeObject 传参进行调用,比如 Web Api 中定义 ...

  6. ASP.NET MVC Web API For APP

    近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过在浏览器中使用 JavaScr ...

  7. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...

  8. 实战 ASP.NET MVC Web API

    实战 ASP.NET MVC Web API Web API 框架基于 ASP.NET MVC 框架开发,是一个面向 Http 协议的通信框架.相对于 WCF 而言,Web API 只面向于 Http ...

  9. ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查. 目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的. 下面我们通过创建一个简单的Web API来管理 ...

随机推荐

  1. 原生JS与jQuery文档加载完毕的写法

    HTML是有执行顺序的,默认是自上而下执行.所以当我们的js代码在html代码下边的时候,可以正常执行,而当我们的js代码在html代码上边的时候,可以就无法正常执行了,这时,我们需要在文档加载完毕的 ...

  2. hibernate中使用HQL进行数据库查询

    1.写的规则比较简单,我讲一下,如图Station这个不是数据库中的表,而是entity包中的类名Station,可以省略 select * 2.返回的类型自动转化为String类型,不用你自己再转化 ...

  3. 认识k_BackingField【转】

    事情从Json的序列化和反序列化说起. 在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行 ...

  4. ZBar Installer

    ZBar Install.For windows:http://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/do ...

  5. base64加密解密文件

    1 //字符串加密 -(void)demo1 { //普通的 8 bit二进制数据 NSString *str = @"hello world!"; //将字符串转换成二进制数据 ...

  6. 实现Bootstrap Carousel Fade Transition 淡入淡出效果

    html代码: <div id="carousel" class="carousel slide carousel-fade" data-ride=&qu ...

  7. POJ 2942.Knights of the Round Table (双连通)

    简要题解: 意在判断哪些点在一个图的  奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...

  8. Bootstrap_表单_表单样式

    一.基础表单 <form > <div class="form-group"> <label>邮箱:</label> <inp ...

  9. getJSON回调函数不执行问题?

    利用getJSON异步请求时,回调函数不执行,不知道是什么问题? php 返回数据 header("Content-type:text/json"); echo json_enco ...

  10. php学习之基础语法

    这些语法都是在学习视频的过程中整理出来的,有些很简单的语法可能就没有整理了,只是记录了自己看来比较重要的语法内容.   1.变量使用 $ 声明 ,变量区分大小写   变量的类型:      4种标量类 ...