解决ASP.NET Web API Json对象循环参考错误
2015-02-11 09:35
344 查看
前言
一般我们在开法ASP.NETWebAPI时,如果是使用EntityFramework技术来操作数据库的话,当两个Entity之间包含导览属性(NavigationProperty)时,而当我们输出的格式为JSON对象时,会出现一个例外,错误讯息为:「'ObjectContent`1'类型无法序列化内容类型'application/json;charset=utf-8'的回应主体。」,而小弟参考了Will保哥以及Bruce两位前辈的文章后,整理出两种小弟觉得比较可行的替代与解决方案。
了解问题
这张图里包含了两张数据表Orders与Order_Details,两者之间存在着一对多的关系,而预设EntityFramework会自动帮我们的关联数据表加入导览属性(NavigationProperty),接着我们往下一张图看下去:
publicIEnumerable<Orders>GetOrders(){returndb.Orders;}
这段程序代码为ValuesController里的一个Function,当我们请求时会返回Orders所有数据,但当我们输入网址/api/Values/请求时却发生了这样的错误:
这个问题发生的原因为,当我们请求某个特定的Enity时会取出该Entity的所有属性内容,当然包夸了导览属性的数据,而究竟这个问题如何照成呢?以目前的案例来看,当我们取得Orders的资料时也会一并取得其导览属性,也就是Order_Details的所有数据,而在Order_Details里也包含着Orders的导览属性,所以又会在去取得Orders的数据....,这样两个实体之间不停的往返就会造成了无限循环,也是我们前面所说的循环参考的错误。
如何解决
方法一:
在开发ASP.NETMVC中,时常会用到部分类别(PartailClass)来为我们的数据域位加上验证属性,所以利用此特性来解决我们的问题,首先在Model数据夹底下新增两个档案分别为:OrdersMetadata.cs、Order_DetailsMetadata.cs
viewsourceprint?
这边我们在在对应的导览属性上都加上「JsonIgnore」的属性,来防止循环参考的问题发生,记得是有关联的两边都要加上「JsonIgnore」的属性。
方法二:
另外一种方法则是利用我们在开发ASP.NETMVC时常用到的ViewModel的概念,针对特定的页面或请求只返回特定的数据,所以这边我们能透过DTO方式来解决我们问题,首先我们先在Model底下新增一个DTO.cs档案:www.it165.net
DTO.cs
viewsourceprint?
并且修改我们原本在WebAPIController里的Function:
viewsourceprint?
总结
两种作法都能解决造成循环对象参考的问题,而在Bruce和Will保哥的文章都指出用第一种方法来解决此循环参考错误是最正确的作法,两种作法算是两种不同的出发点,所以该怎么用应该就是看各位读者如何应用了。
一般我们在开法
了解问题
这张图里包含了两张数据表Orders与Order_Details,两者之间存在着一对多的关系,而预设EntityFramework会自动帮我们的关联数据表加入导览属性(NavigationProperty),接着我们往下一张图看下去:
publicIEnumerable<Orders>GetOrders(){returndb.Orders;}
这段程序代码为ValuesController里的一个Function,当我们请求时会返回Orders所有数据,但当我们输入网址/api/Values/请求时却发生了这样的错误:
这个问题发生的原因为,当我们请求某个特定的Enity时会取出该Entity的所有属性内容,当然包夸了导览属性的数据,而究竟这个问题如何照成呢?以目前的案例来看,当我们取得Orders的资料时也会一并取得其导览属性,也就是Order_Details的所有数据,而在Order_Details里也包含着Orders的导览属性,所以又会在去取得Orders的数据....,这样两个实体之间不停的往返就会造成了无限循环,也是我们前面所说的循环参考的错误。
如何解决
方法一:
在开发
01.
OrdersMetadata.cs
02.
03.
[MetadataType(
typeof
(OrderMD))]
04.
public
partial
class
Order
05.
{
06.
public
class
OrderMD
07.
{
08.
[JsonIgnore()]
//需引用usingNewtonsoft.Json;
09.
public
virtual
ICollection<Order_details>Order_Details{
get
;
set
;}
10.
}
11.
}Order_DetailsMetadata.cs
12.
13.
[MetadataType(
typeof
(Order_DetailsMD))]
14.
public
partial
class
Order_Details
15.
{
16.
public
class
Order_DetailsMD
17.
{
18.
[JsonIgnore()]
//需引用usingNewtonsoft.Json;
19.
public
virtual
OrdersOrders{
get
;
set
;}
20.
}
21.
}
这边我们在在对应的导览属性上都加上「JsonIgnore」的属性,来防止循环参考的问题发生,记得是有关联的两边都要加上「JsonIgnore」的属性。
方法二:
另外一种方法则是利用我们在开发ASP.NETMVC时常用到的ViewModel的概念,针对特定的页面或请求只返回特定的数据,所以这边我们能透过DTO方式来解决我们问题,首先我们先在Model底下新增一个DTO.cs档案:www.it165.net
DTO.cs
01.
public
class
OrderDTO
02.
{
03.
public
int
OrderID{
get
;
set
;}
04.
public
string
CustomerID{
get
;
set
;}
05.
public
int
?EmployeeID{
get
;
set
;}
06.
public
DateTime?OrderDate{
get
;
set
;}
07.
public
List<Order_detailsDTO>Order_Detail{
get
;
set
;}
08.
}
09.
public
class
Order_DetailsDTO
10.
{
11.
public
int
OrderID{
get
;
set
;}
12.
public
decimal
UnitPrice{
get
;
set
;}
13.
public
decimal
Quantity{
get
;
set
;}
14.
}
并且修改我们原本在WebAPIController里的Function:
01.
public
IEnumerable<OrderDTO>GetOrders()
02.
{
03.
NorthwindEntitiesdb=
new
NorthwindEntities();
04.
05.
return
db.Orders.ToList().Select(p=>
new
OrderDTO
06.
{
07.
CustomerID=p.CustomerID,
08.
EmployeeID=p.EmployeeID,
09.
OrderDate=p.OrderDate,
10.
OrderID=p.OrderID,
11.
Order_Detail=p.Order_Details.Select(x=>
new
Order_DetailsDTO
12.
{
13.
OrderID=x.OrderID,
14.
Quantity=x.Quantity,
15.
UnitPrice=x.UnitPrice
16.
}).ToList()
17.
});;
18.
}
总结
两种作法都能解决造成循环对象参考的问题,而在Bruce和Will保哥的文章都指出用第一种方法来解决此循环参考错误是最正确的作法,两种作法算是两种不同的出发点,所以该怎么用应该就是看各位读者如何应用了。
相关文章推荐
- asp.net web api 解决ajax跨站点post请求提交 json 数据问题
- 解决ASP.NET 请求数据太大500错误 JSON无法反序列化
- asp.net运行提示未将对象引用设置到对象的实例错误解决方法
- 解决fastjson内存对象重复/循环引用json错误
- Json.net对于导航属性的处理(解决对象循环引用)
- asp.net web api http put delete , iis 返回400.0 找不到错误的解决办法.
- asp.net web api 解决ajax跨站点post请求提交 json 数据问题
- 【ASP.NET 问题】System.InvalidOperationException: 对象的当前状态使该操作无效 【大量表单数据提交】错误解决
- Asp.net Web API 返回Json对象的两种方式
- Json.net对于导航属性的处理(解决对象循环引用)
- ASP.NET Web Api返回对象类型为JSON还是XML
- asp.net运行提示未将对象引用设置到对象的实例错误解决方法
- 解决fastjson内存对象重复/循环引用json错误
- ASP.NET MVC 解决JSON循环调用的问题
- IIS不支持ASP.NET1.1的错误解决方法
- 在Asp.net中建立Microsoft.Office.Interop.Word.Application时出现“拒绝访问”错误的解决方法
- asp.net登陆数据库的错误解决
- Asp.net Ajax 中的脚本错误: 'Sys'未定义 的解决方法
- 解决[ASP.NET]"编译器错误信息: CS1595: 已在多处定义"的问题
- 报没有启动 ASP.NET State service错误的解决方法