Entity Framework + WCF 远程调用出错
在使用Entity Framework中使用WCF,在程序中调用服务一直报错,我一直以为是WCF的哪个地方的配置有问题,找来找去,一直没有解决。

最后在网上找到一篇文章,说是序列化的问题,我才想起来,原来是跟Entity Framework有关。又是导航属性序列化的问题。觉得真是坑爹,早该想到的。
分析出来,还是因为实体类中有导航属性,而EF会为有导航属性的实体类,生成一个代理类,而这个代理类也有自引用。所以WCF在序列化的时候,就会出错。报的就是上面的这个错误。
一种办法说是禁用生成代理,这个是可以实现的,直接在Context里面禁用就可以了。
this.Configuration.ProxyCreationEnabled = false;
但是如果禁用代理了,就不能通过导航属性得到关联的值了。所以这个方法不可行。在网上找到的另外一种办法就是自定义一个特性。个人开始嫌麻烦,不愿意自定义这个特性。
我想是不是因为有这个导航属性才这样的,所以最开始想能不能让这个导航属性字段不序列化,只序列化其他的字段应该就行了,因为我前台并不需要用到这个导航属性。我在实体里面把导航属性前面的DataMember特性去掉了,最后发现还是报这个错误。后来设计发现,就算把这个特性去掉了,只是代表不序列化,但是这个属性还是有virtual关键字,EF框架还是会为它生成代理类。之所以WCF报错不是因为导航属性序列化的问题,而是因为有导航属性字段,会生成代理类。是代理类的序列化出了问题。
最后还是参照网上的方法,自定义一个特性,然后在接口方法上应用这个特性,才把这个问题解决了。
自定义特性的代码是:
先定义一个类ProxyDataContractResolver:
//DataContractResolver在System.Runtime.Serialization这个命名空间里
public class ProxyDataContractResolver :DataContractResolver
{
private XsdDataContractExporter _exporter = new XsdDataContractExporter();
public override Type ResolveName(string typeName, string typeNamespace, Type declaredType,
DataContractResolver knownTypeResolver)
    {
return knownTypeResolver.ResolveName(
typeName, typeNamespace, declaredType, null);
}
public override bool TryResolveType(Type dataContractType, Type declaredType,
DataContractResolver knownTypeResolver,
out XmlDictionaryString typeName,
out XmlDictionaryString typeNamespace)
    {
Type nonProxyType = ObjectContext.GetObjectType(dataContractType);
if (nonProxyType != dataContractType)
        {
// Type was a proxy type, so map the name to the non-proxy name
XmlQualifiedName qualifiedName = _exporter.GetSchemaTypeName(nonProxyType);
XmlDictionary dictionary = new XmlDictionary(2);
typeName = new XmlDictionaryString(dictionary,
qualifiedName.Name, 0);
typeNamespace = new XmlDictionaryString(dictionary,
qualifiedName.Namespace, 1);
return true;
}
else
        {
// Type was not a proxy type, so do the default
return knownTypeResolver.TryResolveType(
dataContractType,
declaredType,
null,
out typeName,
out typeNamespace);
}
}
}
再定义一个特性类ApplyProxyDataContractResolverAttribute
public class ApplyProxyDataContractResolverAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    {
}
public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
    {
DataContractSerializerOperationBehavior
dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver();
}
public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
    {
DataContractSerializerOperationBehavior
dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver();
}
public void Validate(OperationDescription description)
    {
}
}
然后在接口层的方法上面加上这个特性就可以了。
[OperationContract]
[ApplyProxyDataContractResolverAttribute]
终于可以松一口气了,在使用EF的过程中,一定要考虑到这个导航属性的特殊性。
参考文章:
http://www.cnblogs.com/Gyoung/p/3153875.html(文中的代码都是摘自这篇文章,谢谢!)
Entity Framework + WCF 远程调用出错的更多相关文章
- Entity Framework + WCF REST JSON Service
		利用EF 和WCF 建立一个REST JSON Service. 首先我们要下载一个Visual Studio 的Template 叫 "ADO.NET C# POCO Entity Gen ... 
- 使用Entity Framework时,序列化出错
		在使用Entity Framework时,如果数据库中有两个表是一对多或者是多对多的关系,那么生成的实体类中就有一个导航属性.这个导航属性前面都加上了一个virtual关键字.这个v ... 
- feign远程调用出错
		如果你传递的参数,比较复杂时,默认会采用POST的请求方式. 传递单个参数时,推荐使用@PathVariable,如果传递的单个参数比较多,这里也可以采用@RequestParam,Feign接口中不 ... 
- Entity Framework在WCF中序列化的问题
		问题描述 如果你在WCF中用Entity Framework来获取数据并返回实体对象,那么对下面的错误一定不陌生. 接收对 http://localhost:5115/ReService.svc 的 ... 
- Entity Framework在WCF中序列化的问题(转)
		问题描述 如果你在WCF中用Entity Framework来获取数据并返回实体对象,那么对下面的错误一定不陌生. 接收对 http://localhost:5115/ReService.svc 的 ... 
- Entity framework在用于WCF时创建数据模型的问题
		众所周知,WCF的传输对象,在创建时需要在类名上标识[DataContract]以及在属性上标识[DataMember],当我们在使用Entity framework时(不考虑Code first的情 ... 
- 精进不休 .NET 4.5 (12) - ADO.NET Entity Framework 6.0 新特性, WCF Data Services 5.6 新特性
		[索引页][源码下载] 精进不休 .NET 4.5 (12) - ADO.NET Entity Framework 6.0 新特性, WCF Data Services 5.6 新特性 作者:weba ... 
- ASP.NET  MVC4 & Entity Framework 6.0 IIS 部署出错解决方案
		博客地址 http://blog.csdn.net/foxdave 近期了解MVC4的时候弄了一个简单的小工程,使用Entity Framework作为Model,F5启动调试运行的时候没有问题,但是 ... 
- Metasploit远程调用Nessus出错
		Metasploit远程调用Nessus出错 从Nessus 7.1开始,Metaspliot远程调用Nessus创建新的扫描任务,会出现以下错误信息: [*] New scan added ... 
随机推荐
- linux服务基础之CentOS6编译安装mariadb
			1. 下载mariadb https://downloads.mariadb.org/mariadb/+releases/ 2. 解压到指定目录 # tar xf mariadb--linux-x86 ... 
- CF498D Traffic Jams in the Land
			嘟嘟嘟 题面:有n条公路一次连接着n + 1个城市,每一条公路有一个堵塞时刻a[i],如果当前时间能被a[i]整除,那么通过这条公路需要2分钟:否则需要1分钟. 现给出n条公路的a[i],以及m次操作 ... 
- HDU 1757 A Simple Math Problem 【矩阵经典7 构造矩阵递推式】
			任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1757 A Simple Math Problem Time Limit: 3000/1000 MS (J ... 
- 【luogu P1004 方格取数】 题解
			题目链接:https://www.luogu.org/problemnew/show/P1004 标准的DP,不明白为什么有普及+提高的难度 四维DP[i][j][k][l] 表示第一遍走到i,j格子 ... 
- JS获取浏览器高度和宽度
			IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.d ... 
- JS JavaScript深拷贝、浅拷贝
			浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变. 深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变. 浅拷贝数 ... 
- Linux中软件使用笔记
			刚刚接触Linux的小白,难免会碰到各种小问题,不要灰心,总有办法的... 1.搜狗输入法崩溃,打不出中文?都是乱码?一招制敌! 在Terminal中输入下面命令后重启电脑即可重生- 还有,是Sogo ... 
- 移动端flex自适应方案。(px to rem)
			define(function (require, exports, module) { exports.mobileUtilMethod = function () { (function (e, ... 
- 菜鸟崛起 DB Chapter 2 MySQL 5.6的概述与安装
			在上文菜鸟崛起 DB Chapter 1 数据库概述我们初步认识了数据库,也知道市面上常见的几种数据库,下面我们就针对常见的MySQL数据库展开对DataBase的探讨. 2.1 MySQL介绍 M ... 
- win7  bat copy 一个文件 到另外的文件夹内,路径得用引号哦
			win 7 的 用引号 把路径引起来 ,但是win10 的可以不用哦 ! 
