首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

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

作者头像
蒋金楠
发布2018-01-16 18:01:21
7110
发布2018-01-16 18:01:21
举报
文章被收录于专栏:大内老A大内老A

我们有两种典型的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: }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2009-12-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档