WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现]

(提供模拟程序)

基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetadataBehavior需要做的更多额外的工作。原因很简单,由于在WS-MEX模式下,我们为寄宿的服务添加了相应的MEX终结点,那么当服务被成功寄宿后,WCF已经为元数据的消息交换建立了如图1所示的分发体系,我们需要做的仅仅是对MEX终结点的DispatchRuntime进行相应的定制而已。

图1 WCF服务端分发体系

但是如果采用HTTP-GET模式,实际上我们需要从ChannelDispatcher开始,重新构建整个分发体系。接下来,我们在《WS-MEX原理》提供实例的基础上,对我们自定义ServiceMetadataBehaviorAttribute进行进一步的完善,使之同时对两种模式的元数据发布提供支持。 (Source Code从这里下载)

首先,我们需要定义一个新的服务契约接口:IHttpGetMetadata,Get操作处理任何形式的消息请求,因为它的输入参数和返回类型均为Message,并且Action和ReplyAction为*。

   1: using System.ServiceModel;   2: using System.ServiceModel.Channels;   3: namespace ServiceMetadataBehaviorSimulator   4: {   5:     [ServiceContract(Name = "IHttpGetMetadata", Namespace = "http://www.artech.com/")]   6:     public interface IHttpGetMetadata   7:     {   8:         [OperationContract(Action = "*", ReplyAction = "*")]   9:         Message Get(Message msg);  10:     }  11: }

然后我们让前面定义的MetadataProvisionService实现IHttpGetMetadata接口,在这里无需再写任何多余的代码,因为MetadataProvisionService已经具有了一个Get方法。

   1: public class MetadataProvisionService : IMetadataProvisionService, IHttpGetMetadata   2: {   3:       //省略成员   4: }

接下来的工作就是构建一个全新的ChannelDispatcher,以及关联EndpointDispatcher,最后对EndpointDispatcher的DispatchRuntime进行定制。为此,我单独写了一个方法:CreateHttpGetChannelDispatcher。

   1: [AttributeUsage(AttributeTargets.Class)]   2: public class ServiceMetadataBehaviorAttribute : Attribute, IServiceBehavior   3: {   4:     //其他成员   5: private const string SingletonInstanceContextProviderType = "System.ServiceModel.Dispatcher.SingletonInstanceContextProvider,System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";   6:      private const string SyncMethodInvokerType = "System.ServiceModel.Dispatcher.SyncMethodInvoker,System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";   7:      private const string MessageOperationFormatterType = "System.ServiceModel.Dispatcher.MessageOperationFormatter, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";   8:   9:     private static void CreateHttpGetChannelDispatcher(ServiceHostBase host, Uri listenUri, MetadataSet metadata)  10:     {  11:         //创建Binding  12:         TextMessageEncodingBindingElement messageEncodingElement = new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.None };  13:         HttpTransportBindingElement transportElement = new HttpTransportBindingElement();  14:         Utility.SetPropertyValue(transportElement, "Method", "GET");  15:         Binding binding = new CustomBinding(messageEncodingElement, transportElement);  16:  17:         //创建ChannelListener  18:         IChannelListener listener = binding.BuildChannelListener<IReplyChannel>(listenUri, string.Empty, ListenUriMode.Explicit, new BindingParameterCollection());  19:         ChannelDispatcher dispatcher = new ChannelDispatcher(listener, "ServiceMetadataBehaviorHttpGetBinding", binding) { MessageVersion = binding.MessageVersion };  20:  21:         //创建EndpointDispatcher  22:         EndpointDispatcher endpoint = new EndpointDispatcher(new EndpointAddress(listenUri), "IHttpGetMetadata", "http://www.artech.com/");  23:  24:         //创建DispatchOperation,并设置DispatchMessageFormatter和OperationInvoker  25:         DispatchOperation operation = new DispatchOperation(endpoint.DispatchRuntime, "Get", "*", "*");  26:         operation.Formatter = Utility.CreateInstance<IDispatchMessageFormatter>(MessageOperationFormatterType, Type.EmptyTypes, new object[0]);  27:         MethodInfo method = typeof(IHttpGetMetadata).GetMethod("Get");  28:         operation.Invoker = Utility.CreateInstance<IOperationInvoker>(SyncMethodInvokerType, new Type[] { typeof(MethodInfo) }, new object[] { method });  29:         endpoint.DispatchRuntime.Operations.Add(operation);  30:  31:         //设置SingletonInstanceContext和InstanceContextProvider  32:         MetadataProvisionService serviceInstance = new MetadataProvisionService(metadata);  33:         endpoint.DispatchRuntime.SingletonInstanceContext = new InstanceContext(host, serviceInstance);  34:         endpoint.DispatchRuntime.InstanceContextProvider = Utility.CreateInstance<IInstanceContextProvider>(SingletonInstanceContextProviderType, new Type[] { typeof(DispatchRuntime) }, new object[] { endpoint.DispatchRuntime });  35:         dispatcher.Endpoints.Add(endpoint);  36:  37:         //设置ContractFilter和AddressFilter  38:         endpoint.ContractFilter = new MatchAllMessageFilter();  39:         endpoint.AddressFilter = new MatchAllMessageFilter();  40:  41:         host.ChannelDispatchers.Add(dispatcher);  42:     }  43: }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索new
, system
, endpoint
serviceModel
sql 发布wsdl服务、springmvc发布wsdl、webservice发布wsdl、php wsdl 调用实现、发布wsdl,以便于您获取更多的相关知识。

时间: 2024-10-12 23:32:07

WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现]的相关文章

WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序)

通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配置的方式将ServiceMetadataBehavior这样一个服务形式应用到相应的服务上面,从而实现基于HTTP-GET或者WS-MEX的元数据发布机制.那么在WCF内部具体的实现原理又是怎样的呢?相信很多人对此都心存好奇,本篇文章的内容将围绕着这个主题展开. 一. 从WCF分发体系谈起 如果读者想对WCF内部的元数据发布机制的实现原理有一个全面而深入的了解,必须对WCF服务端的分发体系有一个清晰的认识.在这

WCF技术剖析之二十七: 如何将一个服务发布成WSDL

[基于WS-MEX的实现](提供模拟程序) 通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配置的方式将ServiceMetadataBehavior这样一个服务形式应用到相应的服务上面,从而实现基于HTTP-GET或者WS-MEX的元数据发布机制.那么在WCF内部具体的实现原理又是怎样的呢?相信很多人对此都心存好奇,本篇文章的内容将围绕着这个主题展开. 一. 从WCF分发体系谈起 如果读者想对WCF内部的元数据发布机制的实现原理有一个全面而深入的了解,必须对

WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇]

对于WCF服务端元数据架构体系来说,通过MetadataExporter将服务的终结点导出成MetadataSet(参考<如何导出WCF服务的元数据>),仅仅是完成了一半的工作.被成功导出的以MetadataSet对象表示的元数据需要最终作为可被访问的网络资源发布出来,才能被服务消费者获取,进而有效地帮助他们进行服务调用.元数据的发布最终是通过ServiceMetadataBehavior这样一个服务行为实现的,我们先来认识一下ServiceMetadataBehavior. 一. 元数据发布

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

服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户端传播.对于一般的异常(比如执行Divide操作抛出的DivideByZeroException),在默认的情况下,异常信息无法实现向客户端传递.但是,倘若为某个服务应用了ServiceDebugBehavior这么一个服务行为,并开启了IncludeExceptionDetailInFaults开关,异常信息将会原封不动地传播到客户端.WCF内部是如何处理抛出的非FaultException异常的呢?

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

元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-MEX和HTTP-GET的元数据发布,针对这两种不同的协议,元数据获取的实现方式也是不同的.我们首先来实现基于WS-MEX的元数据获取方式. [Source Code从这里下载] 一. 基于WS-MEX的元数据获取 ServiceMetadataBehavior通过创建MEX终结点实现了基于WS-MEX的元数据的发布,从<如何将一个服务发布成WSDL>系列文章的介绍

WCF技术剖析之二十八:自己动手获取元数据

元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-MEX和HTTP-GET的元数据发布,针对这两种不同的协议,元数据获取的实现方式也是不同的.我们首先来实现基于WS-MEX的元数据获取方式. 本文配套源码:http://www.bianceng.net/dotnet/201212/655.htm 一. 基于WS-MEX的元数据获取 ServiceMetadataBehavior通过创建MEX终结点实现了基于WS-ME

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

通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding元素来源于终结点的绑定对象,那么这些基于Binding的元数据以及相应的策略断言是如何被写入WSDL的呢?WSDL导出扩展(WSDL Export Extension)和策略导出扩展(Policy Export Extension)就是为此设计的. 一.WSDL导出扩展(WSDL Export Extension) 终结点的绑定本质上就是相关的绑定元素(BindingElement)的有序组合(

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

从FaultContractAttribute的定义我们可以看出,该特性可以在同一个目标对象上面多次应用(AllowMultiple = true).这也很好理解:对于同一个服务操作,可能具有不同的异常场景,在不同的情况下,需要抛出不同的异常. 1: [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] 2: public sealed class FaultContractAttri

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

在[第2篇]中,我们深入剖析了单调(PerCall)模式下WCF对服务实例生命周期的控制,现在我们来讨轮另一种极端的服务实例上下文模式:单例(Single)模式.在单例模式下,WCF通过创建一个唯一的服务实例来处理所有的客户端服务调用请求.这是一个极端的服务实例激活方式,由于服务实例的唯一性,所有客户端每次调用的状态能够被保存下来,但是当前的状态是所有客户端作用于服务实例的结果,而不能反映出具体某个客户端多次调用后的状态.WCF是一个典型的多线程的通信框架,对并发的服务调用请求是最基本的能力和要