Let us first think of what the client is going to send to the service?Just a HTTP request.The method may be GET or POST.Suppose I am trying to access a service operation Add(int i,int j) .The client code in C# will be something like as shown below:
HttpWebRequest request = HttpWebRequest.Create(http://localhost:9001/Test/Add/?i=1&j=1) as HttpWebRequest;
request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
request.Method = “GET”;
request.ContentType = “text/xml”;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Before we proceed into the details of the service side let me note the down the questions that initially occurred to my mind.
- How the HTTP message will read and parsed in the service side?
- How from the URI the name of the method Add will be read and request will be dispatched to the correct operation?
- How the parameters will be parsed from the querystring?
In the subsequent sections I will try to answer these questions.
In the server side there should be some program listening to a particular socket waiting for bytes to arrive.This is the job of the ChannelListener as I had discussed in one of my earlier posts titled ServiceHost & Channels.This ChannelListener should be able to read raw bytes and create channels to process the HTTP requests.But the channels are created by the specified binding.So we need a binding which can handle HTTP Transport and encode/decode POX and JSON messages.For this we have a binding provided by WCF called WebHttpBinding.This binding is primarily composed of HttpTransportBindingElement and WebMessageEncodingBindingElement.This WebMessageEncodingBindingElement inherits from TextMessageEncodingBindingElement and is a composite encoder which can handle plain text,XML,JSON and raw binary data.
So to make WCF Services available for basic HTTP clients we need to expose an endpoint with WebHttpBinding.
Now we have an service endpoint ,message is processed by channels created by WebHttpBinding and routed to the EndpointDispatcher via the ChannelDispatcher.But who reads the URI of the message and decides which service operation this is intended for?How the parameters values are parsed from the querystring?
The parsing of URI and determination of operation is done by public string SelectOperation( ref Message message ) method of a WebHttpDispatchOperationSelector class implementing the IDispatchOperationSelector interface.
The querystring parsing and parameter processing is done by a dispatch formatter class implementing the IDispatchFormatter interface with methods:
void DeserializeRequest(Message message, object parameters)
Message SerializeReply(MessageVersion messageVersion, object parameters, object result)
How these two classes gets attached to the DispatchRuntime of the EndpointDispatcher.WCF allows to modify the behaviour of an endpoint using endpoint behaviours.The classes intending to so needs to implement the IEndpointBehavior interface.WCF provides WebHttpBehavior class for modifying the endpoint behavior to suit the needs of POX/JSON messages.This class has three methods to get the operation selector and formatters.
protected virtual WebHttpDispatchOperationSelector GetOperationSelector(ServiceEndpoint endpoint)
protected virtual IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription,ServiceEndpoint endpoint)
protected virtual IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription,ServiceEndpoint endpoint)
In the operation ApplyDispatchBehavior these components are added to the DispatchRuntime
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
endpointDispatcher.DispatchRuntime.OperationSelector = …
How the WebHttpBehavior is added to the ServiceEndPoint??
WCF provides a class called WebServiceHost to host services for web based clients send POX/JSON messages.This class inherits from the ServiceHost class.This class makes sure that WebHttpBinding is properly used and attaches the WebHttpBehavior to the ServiceEndPoint.
Now the last things that I need to mention is the two Operation Behavior attributes that need to be applied to the Service operations:WebInvokeAttribute and WebGetAttribute.These two attributes are passive operation behavior and adds some additional metadata to the operation description.This information is used by the WebHttpBehavior for processing.WebGetAttribute allows only HTTP GET requests whereas WebInvokeAttribute has one Method parameter.This parameter is set to POST by default and can accept GET and PUT as well.
The method signature of the Service operation will look something like:
int Add(int x, int y);
We have covered almost the entire flow of POX/JSON messages from client to service.
In the next post I will discuss how to extend this framework and plug in custom functionalities…