(provides simulation program)
Http-get metadata Publishing is similar to the principle based on Ws-mex, but ServiceMetadataBehavior need to do more work. The reason is simple, because in Ws-mex mode, we add a corresponding MEX endpoint for the hosted service, and when the service is successfully hosted, WCF has established the distribution system, as shown in Figure 1, for the message exchange of the meta data. All we need to do is customize the dispatchruntime of the MEX endpoint.
Figure 1 WCF service-side distribution system
But if we adopt the Http-get model, we actually need to start from ChannelDispatcher and rebuild the entire distribution system. Next, we further refine our custom Servicemetadatabehaviorattribute to provide support for the metadata release of the two schemas, based on the Ws-mex principle, which provides an example. (Source code downloads from here)
First, we need to define a new service contract interface: The Ihttpgetmetadata,get operation handles any form of message request because its input parameters and return types are messages, and action and Replyaction are *.
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 (msg);
: }
11:}
We then let the previously defined Metadataprovisionservice implement the Ihttpgetmetadata interface, where there is no need to write any extra code, because Metadataprovisionservice already has a get method.
1:public class Metadataprovisionservice:imetadataprovisionservice, Ihttpgetmetadata
2: {
3: //ellipsis member
4:}
The next step is to build a brand new ChannelDispatcher, as well as associated EndpointDispatcher, and finally customize EndpointDispatcher's dispatchruntime. To this end, I wrote a separate method: Createhttpgetchanneldispatcher.
1: [AttributeUsage (AttributeTargets.Class)]
2:public class Servicemetadatabehaviorattribute:attribute, IServiceBehavior
3: {
4://other Members
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.servicemode L, version=3.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089 ";
7:private Const string Messageoperationformattertype = "System.ServiceModel.Dispatcher.MessageOperationFormatter, Sy Stem. ServiceModel, version=3.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089 ";
8:
9:private static void Createhttpgetchanneldispatcher (ServiceHostBase host, Uri ListenUri, Metadataset metadata)
10: {
11://Create Binding
12:textmessageencodingbindingelement messageencodingelement = new Textmessageencodingbindingelement () {MessageVe rsion = Messageversion.none};
13:httptransportbindingelement transportelement = new HttpTransportBindingElement ();
14:utility.setpropertyvalue (Transportelement, "method", "get");
15:binding Binding = new CustomBinding (messageencodingelement, transportelement);
16:
17://Create Channellistener
18:ichannellistener listener = binding. Buildchannellistener<ireplychannel> (ListenUri, String. Empty, Listenurimode.explicit, New BindingParameterCollection ());
19:channeldispatcher Dispatcher = new ChannelDispatcher (Listener, "servicemetadatabehaviorhttpgetbinding", Bindin g) {messageversion = binding. MessageVersion};
20:
21://Create EndpointDispatcher
22:endpointdispatcher endpoint = new EndpointDispatcher (new EndpointAddress (ListenUri), "Ihttpgetmetadata", "http ://www.artech.com/");
23:
24://Create DispatchOperation, and set up Dispatchmessageformatter and 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://Set up Singletoninstancecontext and 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://Set up Contractfilter and AddressFilter
38:endpoint. Contractfilter = new Matchallmessagefilter ();
39:endpoint. AddressFilter = new Matchallmessagefilter ();
40:
41:host. Channeldispatchers.add (dispatcher);
42:}
43:}