(提供模拟程序)
基于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,以便于您获取更多的相关知识。