yield在WCF中的错误使用——99%的开发人员都有可能犯的错误[上篇]

在定义API的时候,对于一些返回集合对象的方法,很多人喜欢将返回类型定义成IEnumerable<T>,这本没有什么问题。这里要说的是另一个问题:对于返回类型为IEnumerable<T>的方法来说,我们可以使用yield
return的方式来输出返回集合的元素。但是如果我们不了解yield 关键字背后的实现机制,很有可能造成很大的问题。

这是一个WCF相关的问题,我想99%的人都有可能会犯这样的错误——即使你对yield了解得非常透彻。闲话少说,我们通过一个简单的实例来说明这个问题。我们定义了如下一个IDemoService接口作为服务契约,唯一的方法GetItems返回一个类型为IEnumerable<string>对象,并且具有唯一字符串参数category。

   1:  [ServiceContract]
   2:  public interface IDemoService
   3:  {
   4:      [OperationContract]
   5:      IEnumerable<string> GetItems(string category);
   6:  }

下面是实现了该契约接口的DemoService的实现:GetItems方法返回一个包含3个字符串的集合,但是在返回之前我们需要对参数实施验证。如果category参数提供的字符串为Null或者是空字符串,抛出一个FaultException异常并提示“Invalid
Category”,这样客户端在输入不合法参数的情况下可以得到错误消息。这样的编程方式再正常不过了,不是吗?

public class DemoService : IDemoService
{
    public IEnumerable<string> GetItems(string categoty)
    {
        if (string.IsNullOrEmpty(categoty))
        {
            throw new FaultException("Invalid category");
        }
        yield return "Foo";
        yield return "Bar";
        yield return "Baz";
    }
}

可是正常并不意味着正确,客户端其实根本无法得到服务端提供给它的错误消息,如下所示的是客户端调用服务时指定一个空字符串参数情况下得到的错误。一个CommunicationException异常被抛出来,得到的错误消息为“An
error occurred while receiving the HTTP response to http://127.0.0.1:3721/demoservice.
This could be due to the service endpoint binding not using the HTTP
protocol. This could also be due to an HTTP request context being
aborted by the server (possibly due to the service shutting down). See
server logs for more details.”

这貌似和我们预期的效果不一样,我们希望的是客户端抛出一个FaultException,并提示“Invalid
category”。这实际上就是因为“yield”在作祟,不相信的话可以将定义在DemoService的GetItems方法替换成如下的定义,即直接返回一个string[]对像。

public class DemoService : IDemoService
{
    public IEnumerable<string> GetItems(string categoty)
    {
        if (string.IsNullOrEmpty(categoty))
        {
            throw new FaultException("Invalid category");
        }
        return new  { "Foo", "Bar", "Baz" };
    }
}

再次运行我们的程序,这回可以得到我们期望的结果了。

有兴趣的朋友可以思考一下为什么两种貌似等效的方式为何会出现完全不同的结果,具体原因请看[下篇]

yield在WCF中的错误使用——99%的开发人员都有可能犯的错误[上篇]

yield在WCF中的错误使用——99%的开发人员都有可能犯的错误[下篇]

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2022-12-16

yield在WCF中的错误使用——99%的开发人员都有可能犯的错误[上篇]的相关文章

(译)开发人员经常犯的8个设计错误

设计师在抱怨开发人员不尊重Web标准,后台开发人员在抱怨为什么不可以增加一个空格.PM在抱怨为什么项目总是因为那些看似简单的问题而延期--如何才能提高后台开发人员与设计师以及前端开发工程师的合作效率?相信很多网站或软件开发公司都越到类似的问题. 从UED的角度而言,我们的天职是追求用户体验.我们应该尽力坚持自己应该坚持的东西.白鸦曾经说过,用户体验不只是UED的事情,而是整个开发团队乃至整个公司需要参与的事情. 我们不能只是抱怨,我们去理解开发人员.同样,我们做出努力,让开发人员去理解我们. 我

Access 开发人员常犯错误大全_ASP基础

错误一:陷入界面设计陷阱.漂亮的姑娘喜欢穿美丽的衣服,丑姑娘也喜欢美丽的衣服,可ACCESS除了提供定制菜单与开关面版之外,不提供任何定制控键的功能.你如果想使用自己的按扭,得编写许多许多代码,非常麻烦.为什么,为什么你们总放着现成的菜单不用,而要自己编写一整界面.累不累.值得吗,有没有人愿意为你的界面支付更多钱.     错误二:不使用DAO,而使用ADO.请记住DAO是世界上访问mdb文件有最高效率的数据库引擎,因为DAO直接内嵌在ACCESS运行环境中.在ACCESS中使用ADO如同打电话

Access 开发人员常犯错误大全

错误一:陷入界面设计陷阱.漂亮的姑娘喜欢穿美丽的衣服,丑姑娘也喜欢美丽的衣服,可ACCESS除了提供定制菜单与开关面版之外,不提供任何定制控键的功能.你如果想使用自己的按扭,得编写许多许多代码,非常麻烦.为什么,为什么你们总放着现成的菜单不用,而要自己编写一整界面.累不累.值得吗,有没有人愿意为你的界面支付更多钱. 错误二:不使用DAO,而使用ADO.请记住DAO是世界上访问mdb文件有最高效率的数据库引擎,因为DAO直接内嵌在ACCESS运行环境中.在ACCESS中使用ADO如同打电话给坐在桌

23. 产设计人员常犯的错误

23.1. 花80%时间开发使用率不到20%的功能 故事一:网站页面有一个处需要每个月改动一次,产品设计人员提出需要在后台增加一个功能,用来设置该功能. 故事二:产品设计人员要求很多控制开关都做在后台,可以开启与禁用很多功能,这些功能一周,甚至一个月都不会用到一次. 我认为有很多功能一个月改动一次,甚至一年才会变动一次,完全没有必要做成动态功能,如果把这些不必要的功能都做成动态的还会影响页面载入速度. 23.2. 伪需求 什么是伪需求?简言之:看似有这种需求,但其实这种需求是经不起使用频次,用户

Web应用开发人员最易犯的九个安全错误

Web应用程序开发是一个很宽泛的话题.本文仅讨论Web应用开发者应当避免的安全错误.这些错误涉及到任何开发者都不应当忽视的基本安全原则. 开发者应当注意哪些基本的安全原则?应当避免哪些安全错误?为回答这些问题,下面的建议可以回答上述问题. 自以为是:开发自己的安全方法 有些开发者错误地认为自己的算法或认证方法更安全:毕竟黑客从未见识过这种方法,所以他们在破解时会更困难.果真如此吗? 答案是否定的.开发者自己开发认证或登录方法是一个错误,因为他会犯一个或一些黑客能够发现的错误.开发者应当依靠现有的

网站开发人员经常最常见的CSS错误

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 CSS代码很容易,但在相同的时间就变得复杂起来,当你写CSS代码,专业,高规模,高的性能水平.如果你是新进入的网站设计与开发,有更多的机会,你被困在CSS中,如果你不留意.下面是一些常见的错误,很多新手Web开发人员经常犯,而他们玩的CSS. • 结合不当CSS网站复位内! 值得注意的是,CSS复位,帮助开发者使网站的所有元素在所有的浏览器,

使用RSA V7.5中的UML-to-JPA转换加速JPA开发

本文介绍 Rational Software Architect(RSA)V7.5 中最新的 UML-to-JPA 转换,它允许使用者在 UML 对象模型上进行 JPA 配置和数据模型设计,并能快 速生成带 JPA 注解的 Java 类,可以将开发人员从频繁的重复工作中解放出来 .当在 O/R Mapping 开发过程中因需求变化而带来模型和代码的频繁变化时, 使用 RSA 的 UML-to-JPA 转换工具可以有效的降低项目迭代中的重复工作,同 时也有利于保证对象模型和数据模型的一致性,对于应

中的契约-wcf中数据类型契约包括消息契约与错误契约吗?

问题描述 wcf中数据类型契约包括消息契约与错误契约吗? 在wcf中数据类型契约包括消息契约与错误契约吗?数据类型契约包括什么契约呢?? 解决方案 方法.复杂类型.枚举等等都可以定义成契约. 解决方案二: 那数据类型契约包括消息契约与错误契约不咯???.

wcf中数据类型的契约包括错误契约与消息契约吗??

问题描述 wcf中数据类型的契约包括错误契约与消息契约吗?? 解决方案 解决方案二:WCF中有数据契约,消息契约和错误契约.不知道你要问什么?参考:http://www.cnblogs.com/Hlia/p/3149893.html解决方案三:查询了一下根据我的理解不包括解决方案四:数据契约是数据契约,在soap的内容部分传递,消息契约是消息契约,在soap的头信息部分传递至于错误契约,从没听过,只有一个可以被传到到客户端的异常FaultException及它的泛型类型异常FaultExcept