![换种不同的方式调用WCF服务[提供源代码下载]](http://pic.xiahunao.cn/yaotu/换种不同的方式调用WCF服务[提供源代码下载])
我们有两种典型的WCF调用方式通过SvcUtil.exe或者添加Web引用导入发布的服务元数据生成服务代理相关的代码和配置通过ChannelFactoryTChannel创建服务代理对象。在这篇文章中我们采用一种独特的方式进行服务的调用。从本质上讲我们只要能够创建于服务端相匹配的终结点就能够实现正常的服务调用。在WCF客户端元数据架构体系中利用MetadataExchangeClient可以获取服务的元数据而利用MetadataImporter将获取的元数据导入成ServiceEndpoint对象。在本例中我们将利用这两个组件定义了一个独特的服务调用的简单的例子相信可以帮助读者进一步加深对WCF元数据框架体系的理解。 (Source从这里下载)我们依然采用我们熟悉的计算服务的例子下面是该服务相应的服务契约、服务类型的定义和寄宿该服务采用的配置。1: using System.ServiceModel;2: namespace Artech.ServiceInvocationViaMetadata.Contracts3: {4: [ServiceContract(Namespace http://www.artech.com/)]5: public interface ICalculator6: {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.Services5: {6: public class CalculatorService : ICalculator7: {8: public double Add(double x, double y)9: {10: return x y;11: }12: }13: }配置1: ?xml version1.0 encodingutf-8 ?2: configuration3: system.serviceModel4: behaviors5: serviceBehaviors6: behavior namemexBehavior7: serviceMetadata /8: /behavior9: /serviceBehaviors10: /behaviors11: services12: service behaviorConfigurationmexBehavior nameArtech.ServiceInvocationViaMetadata.Services.CalculatorService13: endpoint addresshttp://127.0.0.1:3721/calculatorservice bindingws2007HttpBinding contractArtech.ServiceInvocationViaMetadata.Contracts.ICalculator /14: endpoint addresshttp://127.0.0.1:3721/calculatorservice/mex bindingmexHttpBinding contractIMetadataExchange /15: /service16: /services17: /system.serviceModel18: /configuration从上面的配置我们可以看到服务的元数据通过WS-MEX模式发布出来发布的地址和采用的MEX绑定分别为http://127.0.0.1:3721/calculatorservice/mex和mexHttpBinding。接下来我们就可以通过下面的方式对该服务进行调用了。我们先创建MetadataExchangeClient对象并利用它获取包含元数据的MetadataSet对象并利用该对象创建WsdlImporter对象。接下来我们将基于ICalculator接口的服务契约添加到该WsdlImporter的已知契约列表中调用ImportAllEndpoints方法得到导入的ServiceEndpoint列表。最后根据导出的ServiceEndpoint对象创建ChannelFactoryICalculator对象并创建服务代理进行服务调用。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.Client7: {8: class Program9: {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 (ChannelFactoryICalculator channelFactory new ChannelFactoryICalculator(endpoints[0]))20: {21: ICalculator calculator channelFactory.CreateChannel();22: using (calculator as IDisposable)23: {24: try25: {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: }