Over the past few weeks, I have been writing a subsystem in WCF for a client to process incoming SMS Messages from a telecom gateway. I originally wrote my code using the TCP Binding so that I could easily test the transport using a proxy. Once that was working, I added the wsHttpBindings and recompiled my service. I hosted the service in IIS 7.0 and attempted to send simulated sms text messges to it. As long as I used the client, I had no problems, but when I attempted to send a query directly to the service via IE, everything went to hell in a handbasket.
I have a copy of Michele Leroux Bustamante’s excellent book titled Learning WCF. I turned to the book and reread the bindings portions looking for something that could help me solve my problem. Nothing! I got a copy of Juval Lowy’s book Programming WCF. Again no help! I had a copy of Scott Klein’s book Professional WCF Programming, again no help. At this point, I’m starting to freak. I have this client, to whom I’ve made a commitment and I”ve yet to deliver a workable solution.
I googled combinations of HTTP Get Request and WCF along with a number of other keywords, looking for anything which would help me. I finally stumbled across the following link: http://msdn.microsoft.com/en-us/library/aa395208.aspx which talked about using the REST protocol to intercept HTTP requests and process the message according to the supplied keyword. In the article, they give numerous examples of how to intercept incoming HTTP Requests using HttpRequestMessageProperty to process the messages and use HttpResponseMessageProperty to respond.
EUREKA!!!!!
After many sleepless nights, I had finally found a clue to how to solve my problem. Further investigation revealed a binding called WebHTTPBinging. I looked in the 3 books I had on WCF Progrmaming and none of them mentioned this binding or anything associated with handling webrequest using WCF. I couldn’t believe that it wasn’t even mentioned by these three top caliber authors. I have to believe that there are many more people out there struggling with this same problem.
So here goes:
This is the settings in the webconfig that you need to make to utilize the REST protocol and straight HTTP request.
<system.serviceModel> <services> <service name="MyService.Service" behaviorConfiguration="MyService.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="webHttpBinding" behaviorConfiguration="custom" contract="MyService.ISmsMessageService"> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <endpointBehaviors> <behavior name="custom"> <webHttp/> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name="MyService.Service1Behavior"> <serviceMetadata httpGetEnabled="true"/> serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> The two larger texts are the keys to making this work in the webconfig file. There is another replacement for the <webHttp> element: <enableWebScript> which is used in AJAX calls. The following code shows how to use the HttpRequestMessageProperty and the HttpResponseMessageProperty. public Message ProcessMessage(Message request) { Message response = null; HttpRequestMessageProperty requestProperties = (HttpRequestMessageProperty)request.Properties [HttpRequestMessageProperty.Name]; if (requestProperties != null) { if (String.Equals("GET", requestProperties.Method, StringComparison.OrdinalIgnoreCase)) { //We will process the request at this point. string queryString = requestProperties.QueryString if (!string.IsNullOrEmpty(queryString)) { this.ProcessSmsResponse(queryString); } else { WriteToTextLog.WriteLine("Empty Query String"); } } else { response = Message.CreateMessage(MessageVersion.None, String.Empty, String.Empty); HttpResponseMessageProperty rp = new HttpResponseMessageProperty(); rp.StatusCode = HttpStatusCode.MethodNotAllowed; response.Properties.Add (HttpResponseMessageProperty.Name, responseProperty); } } else { throw new InvalidOperationException ("This service requires the HTTP transport"); } return response; } That’s about all there is to it. I can’t believe its not mentioned anywhere in the Mainstream literature. But, oh well, I stumbled across what I needed, when I needed it and was able to solve my problem and deliver my code to the client. I just hope that this post may help someone avoid the hurdles that I had to jump over the last few weeks.