C# yield在WCF中的错误用法(一)

 更新时间:2015年04月10日 11:09:01   投稿:junjie  
这篇文章主要介绍了C# yield在WCF中的错误使用(一),本文讲解的内容据说是99%的开发人员都有可能犯的错误,需要的朋友可以参考下

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

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

复制代码 代码如下:

  [ServiceContract]
  public interface IDemoService
  {
      [OperationContract]
      IEnumerable<string> GetItems(string category);
  }

下面是实现了该契约接口的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 string[] { "Foo", "Bar", "Baz" };
    }
}

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

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

相关文章

  • c#实现数据库事务示例分享

    c#实现数据库事务示例分享

    这篇文章主要介绍了c#执行多条sql更新语句实现数据库事务的示例,大家参考使用吧
    2014-01-01
  • C# CAD SelectionFilter下TypedValue数组使用方式

    C# CAD SelectionFilter下TypedValue数组使用方式

    这篇文章主要介绍了C# CAD SelectionFilter下TypedValue数组使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • C#中事件只能在内部调用的原因分析

    C#中事件只能在内部调用的原因分析

    事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件,这篇文章主要介绍了C#中事件为什么只能在内部调用,需要的朋友可以参考下
    2021-11-11
  • 详细聊聊如何在C#循环中捕获局部变量

    详细聊聊如何在C#循环中捕获局部变量

    这篇文章主要给大家介绍了关于如何在C#循环中捕获局部变量的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • 浅析C#更改令牌ChangeToken

    浅析C#更改令牌ChangeToken

    这篇文章主要介绍了C#更改令牌ChangeToken,文中运用大量代码讲解的非常详细,感兴趣的小伙伴一起来看看这篇文章吧
    2021-09-09
  • 利用C#实现进程管理器

    利用C#实现进程管理器

    这篇文章主要为大家详细介绍了如何利用C#实现自己的进程管理器,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-12-12
  • C#中Hashtable和Dictionary的区别与用法示例

    C#中Hashtable和Dictionary的区别与用法示例

    由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代。所以这篇文章主要给大家介绍了关于C#中Hashtable和Dictionary区别的相关资料,需要的朋友可以参考下
    2021-05-05
  • C#实现 Server-sent Events的步骤

    C#实现 Server-sent Events的步骤

    这篇文章主要介绍了C#实现 Server-sent Events的步骤,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2021-01-01
  • C#生成不重复随机数列表实例

    C#生成不重复随机数列表实例

    C#生成不重复随机数列表实例的代码,需要的朋友可以参考一下
    2013-02-02
  • C#中List转IList的实现

    C#中List转IList的实现

    本文主要介绍了C#中List转IList的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07

最新评论