原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码和配置;通过ChannelFactory<TChannel>创建服务代理对象。在这篇文章中,我们采用一种独特的方式进行服务的调用。从本质上讲,我们只要能够创建于服务端相匹配的终结点,就能够实现正常的服务调用。在WCF客户端元数据架构体系中,利用MetadataExchangeClient可以获取服务的元数据,而利用MetadataImporter将获取的元数据导入成ServiceEndpoint对象。在本例中,我们将利用这两个组件定义了一个独特的服务调用的简单的例子,相信可以帮助读者进一步加深对WCF元数据框架体系的理解。 (Source从这里下载)

我们依然采用我们熟悉的计算服务的例子,下面是该服务相应的服务契约、服务类型的定义和寄宿该服务采用的配置。

   1: using System.ServiceModel;

   2: namespace Artech.ServiceInvocationViaMetadata.Contracts

   3: {

   4:     [ServiceContract(Namespace = "http://www.artech.com/")]

   5:     public interface ICalculator

   6:     {

   7:         [OperationContract]

   8:         double Add(double x, double y);

   9:     }

  10: }

服务类型:

   1: using System.ServiceModel;

   2: using Artech.ServiceInvocationViaMetadata.Contracts;

   3:  

   4: namespace Artech.ServiceInvocationViaMetadata.Services

   5: {

   6:     public class CalculatorService : ICalculator

   7:     {

   8:         public double Add(double x, double y)

   9:         {

  10:             return x + y;

  11:         }

  12:     }

  13: }

配置:

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <configuration>

   3:     <system.serviceModel>

   4:         <behaviors>

   5:             <serviceBehaviors>

   6:                 <behavior name="mexBehavior">

   7:                     <serviceMetadata />

   8:                 </behavior>

   9:             </serviceBehaviors>

  10:         </behaviors>

  11:         <services>

  12:             <service behaviorConfiguration="mexBehavior" name="Artech.ServiceInvocationViaMetadata.Services.CalculatorService">

  13:                 <endpoint address="http://127.0.0.1:3721/calculatorservice" binding="ws2007HttpBinding" contract="Artech.ServiceInvocationViaMetadata.Contracts.ICalculator" />

  14:                 <endpoint address="http://127.0.0.1:3721/calculatorservice/mex" binding="mexHttpBinding" contract="IMetadataExchange" />

  15:             </service>

  16:         </services>

  17:     </system.serviceModel>

  18: </configuration>

从上面的配置我们可以看到,服务的元数据通过WS-MEX模式发布出来,发布的地址和采用的MEX绑定分别为:http://127.0.0.1:3721/calculatorservice/mex和mexHttpBinding。

接下来,我们就可以通过下面的方式对该服务进行调用了。我们先创建MetadataExchangeClient对象并利用它获取包含元数据的MetadataSet对象,并利用该对象创建WsdlImporter对象。接下来,我们将基于ICalculator接口的服务契约添加到该WsdlImporter的已知契约列表中,调用ImportAllEndpoints方法得到导入的ServiceEndpoint列表。最后根据导出的ServiceEndpoint对象创建ChannelFactory<ICalculator>对象,并创建服务代理进行服务调用。

   1: sing System;

   2: using System.ServiceModel;

   3: using System.ServiceModel.Description;

   4: using System.Xml;

   5: using Artech.ServiceInvocationViaMetadata.Contracts;

   6: namespace Artech.ServiceInvocationViaMetadata.Client

   7: {

   8:     class Program

   9:     {

  10:         static void Main(string[] args)

  11:         {

  12:             MetadataExchangeClient metadataExchangeClient = new MetadataExchangeClient(MetadataExchangeBindings.CreateMexHttpBinding());

  13:             MetadataSet metadata = metadataExchangeClient.GetMetadata(new EndpointAddress("http://127.0.0.1:3721/calculatorservice/mex"));

  14:             WsdlImporter wsdlImporter = new WsdlImporter(metadata);

  15:             //添加已知契约类型

  16:             ContractDescription contract = ContractDescription.GetContract(typeof(ICalculator));

  17:             wsdlImporter.KnownContracts.Add(new XmlQualifiedName(contract.Name, contract.Namespace), contract);

  18:             ServiceEndpointCollection endpoints = wsdlImporter.ImportAllEndpoints();

  19:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(endpoints[0]))

  20:             {

  21:                 ICalculator calculator = channelFactory.CreateChannel();

  22:                 using (calculator as IDisposable)

  23:                 {

  24:                     try

  25:                     {

  26:                         Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2));

  27:                     }

  28:                     catch(TimeoutException)

  29:                     {

  30:                         (calculator as ICommunicationObject).Abort();

  31:                         throw;

  32:                     }

  33:                     catch(CommunicationException)

  34:                     {

  35:                         (calculator as ICommunicationObject).Abort();

  36:                         throw;

  37:                     }

  38:                 }

  39:             }

  40:             Console.Read();

  41:         }

  42:     }

  43: }

作者:Artech
出处:http://artech.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]的更多相关文章

  1. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-ME ...

  2. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...

  3. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...

  4. WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]

    原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...

  5. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

  6. WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  7. WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?

    原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过 ...

  8. WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇]

    原文:WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇] 在[第2篇]中,我们深入剖析了单调(PerCall)模式下WCF对服务实例生命周期的控制,现在我们来 ...

  9. WCF技术剖析之二十一:WCF基本异常处理模式[中篇]

    原文:WCF技术剖析之二十一:WCF基本异常处理模式[中篇] 通过WCF基本的异常处理模式[上篇], 我们知道了:在默认的情况下,服务端在执行某个服务操作时抛出的异常(在这里指非FaultExcept ...

随机推荐

  1. HtmlUnit+Jsoup 解决爬虫无法解析执行javascript的问题

    本人最近在研究爬虫.作为一个新手.研究了些爬虫框架,发现所有开源的爬虫框架很多,功能也很齐全,但唯独遗憾的是,目前还没有发现那个爬虫对js完美的解释并执行.看了浅谈网络爬虫爬js动态加载网页(二)之后 ...

  2. GCD详细使用笔记

    第一.通过GCD创建队列(Queue) 创建队列方式有以下几种: 1.创建一个串行队列: dispatch_queue_t queue =dispatch_queue_create("串行队 ...

  3. foreach学习笔记

    对集合进行遍历 只能获取集合元素,但是不能对集合进行操作. 迭代器除了遍历,还可以进行remove的动作. 如果是用ListIterator,还可以在遍历过程中进行增删改查的动作. for(Strin ...

  4. centos6.5配置163的yum源

    CentOS系统自带的更新源的速度实在是慢,为了让CentOS6使用速度更快的YUM更新源,可以选择163(网易)的更新源. 1.下载repo文件 wget http://mirrors.163.co ...

  5. Java疯狂讲义(三)

  6. GSAP学习笔记

    GSAP(Green Sock Animation Platform)是一个十分好用的js动画库,据说是as的精简版 以下是学习GSAP的一些笔记:貌似中文的文档不是很多 GSAP notes: tl ...

  7. KbmMW两种查询结果集通讯方式

    KbmMW本身可以用QueryService的方式进行远程数据查询,但是SmpileService同样具有很强的扩展性可以实现数据查询,下面展示两种基于SmpileService的远程数据查询方法,其 ...

  8. 邀请朋友富途开户赢iPhone6的史上最强攻略

    最近有关沪港通的消息很多,加上阿里巴巴马上IPO,所以上个月我在朋友推荐下,来富途开了个户.本来对邀请不太感兴趣,但这次的奖品实在诱人,因为超级想要iPhone6,所以也加入了邀请大队.到发贴的时候, ...

  9. CentOS中使用shell的命令补全

    习惯debian的用户都知道shell中的自动补全功能非常实用,其中在CentOS中也可以有同样的功能. 只需要安装 bash-completion 包即可. rpm -ivh http://www. ...

  10. 队列的定义与实现(C语言实现)

    小时候.我们做早操的时候或者军训的时候,都排成一列,有头有尾.如果你迟到了,仅仅能站到最后面一个.退场的时候.都是由第一个先走的.这就是队列雏形. 队列的定义 队列是一种特殊的线性表 队列仅在线性表的 ...