在使用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 远程调用出错的更多相关文章

  1. Entity Framework + WCF REST JSON Service

    利用EF 和WCF 建立一个REST JSON Service. 首先我们要下载一个Visual Studio 的Template 叫 "ADO.NET C# POCO Entity Gen ...

  2. 使用Entity Framework时,序列化出错

             在使用Entity Framework时,如果数据库中有两个表是一对多或者是多对多的关系,那么生成的实体类中就有一个导航属性.这个导航属性前面都加上了一个virtual关键字.这个v ...

  3. feign远程调用出错

    如果你传递的参数,比较复杂时,默认会采用POST的请求方式. 传递单个参数时,推荐使用@PathVariable,如果传递的单个参数比较多,这里也可以采用@RequestParam,Feign接口中不 ...

  4. Entity Framework在WCF中序列化的问题

    问题描述 如果你在WCF中用Entity Framework来获取数据并返回实体对象,那么对下面的错误一定不陌生. 接收对 http://localhost:5115/ReService.svc 的 ...

  5. Entity Framework在WCF中序列化的问题(转)

    问题描述 如果你在WCF中用Entity Framework来获取数据并返回实体对象,那么对下面的错误一定不陌生. 接收对 http://localhost:5115/ReService.svc 的 ...

  6. Entity framework在用于WCF时创建数据模型的问题

    众所周知,WCF的传输对象,在创建时需要在类名上标识[DataContract]以及在属性上标识[DataMember],当我们在使用Entity framework时(不考虑Code first的情 ...

  7. 精进不休 .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 ...

  8. ASP.NET MVC4 & Entity Framework 6.0 IIS 部署出错解决方案

    博客地址 http://blog.csdn.net/foxdave 近期了解MVC4的时候弄了一个简单的小工程,使用Entity Framework作为Model,F5启动调试运行的时候没有问题,但是 ...

  9. Metasploit远程调用Nessus出错

    Metasploit远程调用Nessus出错   从Nessus 7.1开始,Metaspliot远程调用Nessus创建新的扫描任务,会出现以下错误信息:   [*] New scan added ...

随机推荐

  1. userdel

    功能说明:用于删除指定的用户及该用户相关的文件. 参数选项:-f 强制删除用户,即使用户当前已登录.-r 删除用户的同时,删除与用户相关的所有文件. 说明:尽量不要用userdel删除用户,而是采用在 ...

  2. windows 网络通讯模型Overlapped (转)(未看)

    https://blog.csdn.net/jofranks/article/details/7895316 https://blog.csdn.net/caoshiying/article/deta ...

  3. (第六场)Heritage of skywalkert 【玄学】

    题目链接:https://www.nowcoder.com/acm/contest/144/J 标题:J.Heritage of skywalkert | 时间限制:1 秒 | 内存限制:256M s ...

  4. 【luogu T34117 打油门】 题解

    王强怎么这么强啊 王强太强了 二维树状数组 #include <cstdio> #include <cstring> #include <iostream> #in ...

  5. 【luogu P2984 [USACO10FEB]给巧克力Chocolate Giving】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2984 练习SPFA,把FJ当做起点,求出到所有牛的最短路,再把两个牛的相加. #include <cs ...

  6. lucene&solr学习——solr学习(一)

    1.什么是solr solr是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文检索服务器.Solr提供了比lucene风味丰富的查询语言,同时实现了可配置,可扩展,并对索 ...

  7. 创建VS工程使用神经网络库——FANN

    编译: sourceforge上的FANN库带VS2010的工程,我机器上装的VS2005,用不了,愁人,只能手动创建工程了,编译不过,度娘不管用,FQ麻烦,用雅虎搜到一个工程的创建配置,调整配置试一 ...

  8. 分享一个带有合计行功能的DataGridView扩展

    因为一个Winform的项目中需要用到带有合计行的表格,并且需要满足以下需求: 合计行可自动对需要求和的列进行求和计算; 合计行必须固定(冻结)在表格的最底部,且其位置不受滚动条的滚动而移动; 可以设 ...

  9. SQL3120W 不能将xx的字段值转换成 INTEGER值

    一次用DB2 Load/Import导入数据时,报错,提示SQL3120W 不能将xx的字段值转换成 INTEGER值,但目标列不可为空.未装入该行. 目标表: CREATE TABLE TEST( ...

  10. spring入门(七) spring mvc+mybatis+generator

    1.Mybatis-Generator下载 地址:https://github.com/mybatis/generator/releases 我使用的是 mybatis-generator-core- ...