WCF In ASP.Net Demystified

WCF is obvious a great tool in a distributed environment, especially as a web developer I used it every day as the Ajax back end, or restful service that can be consumed by any kind client php, java, ruby on rails etc you name it.

WCF is notorious about its complexity of configuration, plus the capability of different type of hosting, dependency on various .NET versions, it normally scares you off or you end up copying the code or configuration from somewhere and use it without real understanding. And it magically worked until one day…

Here I am going to demystify its use in ASP.NET and hopefully you can get more confidence dealing with WCF after you have read this article.

WCF can be hosted in windows as a windows service, console application, using all sorts of communication protocols, the thing is you DO NOT need to know that, and I believe most of use cases for WCF are for web applications, so here I am going to focus on its use in ASP.NET application and IIS as its host.

1. First and for most a WCF service(not the comsumer) is a ServiceHost which has an endpoint.

<pre>CalculatorService service = new CalculatorService();
ServiceHost serviceHost = new ServiceHost(service, baseAddress);

// Open the ServiceHost to start listening for messages.
serviceHost.Open();

//.....

// Close the ServiceHost.
serviceHost.Close();

While you do not see this piece of code anywhere in ASp.Net as IIS creates ServiceHost for you based on following markup file

2. In ASP.NET, the ServiceHost is activated by ServiceHostFactory

<pre><% @ServiceHost Factory=”DerivedFactory” Service=”MyService” %></pre>

This is telling Asp.Net to create a ServiceHost for MyService, you might not see Factory setting, in that case it is using ServiceHostFactory.

3. When ServiceHostFactory tries to activate an endpoint, configuration will be loaded using service name match. you can even implement your own ServiceHostFactory and twist those configuration settings in any way you like

3.1. Remember configuration free wcf service? it uses WebScriptServiceHostFactory, the reason it is congfiuration free is WebScriptServiceHostFactory is a subclass of ServiceHostFactory
, and loads a DEFAULT set of configuration for your wcf service.

The default configuration loaded by WebScriptServiceHostFactory :

Binding: WebHttpBinding, the binding used by Ajax and restful wcf

WebScriptEnablingBehavior as default setting

3.2. In .Net 4.0 you do not even need any ServiceHostFactory or configuration to make wcf endpoint to work, as again, if there is not ServiceHostFactory nor configuration, NET 4 will create the endpoint using DEFAULT settings, as what are those default settings you can check them out from developer’s guide here

4. We now know what ServiceHostFactory does, and what kind of default values are loaded when you have not done any configuration. Sooner or later, you will find those default configurations will not satisfy your requirement, for example you need to download a big message, that is above the default limit..

A more confident way using wcf is always having your own configuration, and do not have any ServiceHostFactory, it is time to have a look at those configuration settings and try to understand them, at the end of day, WCF as an endpoint needs a set of configuration to work in ALL circumstances either it is defined by you or loaded by frame work.

5. First important concept is binding, there are many bindings, but the binding used by ASP.NET for Ajax or restful service is WebHttpBinding, so can we forget about other bindings please? sure we can. This is the binding used by Ajax and Restful services, most used two scenarios in ASP.NET.

6. An example of Ajax service configuration :

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />

<!--config of serialization-->
    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <!--json serialization wrapped in "d" -->
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="jsonBinding" maxBufferSize="1048576" maxBufferPoolSize="4194304" maxReceivedMessageSize="1048576">
          <readerQuotas maxStringContentLength="1048576"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="YourService">
        <endpoint name="YourServiceEndpoint" contract="YourService" address="" listenUriMode="Explicit" behaviorConfiguration="jsonBehavior" binding="webHttpBinding" bindingConfiguration="jsonBinding"/>
      </service>
    </services>
  </system.serviceModel>

So you can see here this defined an endpoint behavior ‘jsonBehavior’, webHttpBinding controlled by ‘jsonBinding’, at the binding configuration level you can ignore those elements if you are happy about the default values, here is only an example, and you can find those configuration elements documents from MSDN,
One thing I need to point out is the

   <service name="YourService">

This name must be your service class name.

enableWebScript in endpointbehaviour makes json object wrapped under root ‘d’ like {“d”:…}, if you take out this, just ensure you are not breaking your service consuming code.

7. An example for wcf Restful

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />

    <!--config of serialization-->
    <behaviors>
      <endpointBehaviors>

        <!--behavior used by public rest web service-->
        <behavior name="wcfrestendpointbehavior">
          <!--json serialization clean-->
          <webHttp/>
        </behavior>

      </endpointBehaviors>
      <serviceBehaviors>

        <!--behavior used by public rest web service-->
        <behavior name="wcfrestbehavior">
          <serviceMetadata httpGetEnabled="true"/>
         </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <!--public rest web service-->
      <service name="YourWebsericeNameSpace.YourWebService" behaviorConfiguration="wcfrestbehavior">
       <endpoint address="" binding="webHttpBinding" contract="YourWebsericeNameSpace.YourWebService" behaviorConfiguration="wcfrestendpointbehavior" />
      </service>

    </services>
  </system.serviceModel>

Here you can see compared with example above there are a few changes:

Endpoint behavior is using webHttp, if your service returns json object, it IS NOT wrapped under ‘d’.
It does not have a WebHttpBinding configration, as it is happy about the default values
Service comes with a name space: YourWebsericeNameSpace.YourWebService

8.To complete the example here is service.svc and service.cs

<%@ ServiceHost Language="C#" Debug="true" Service="Service"
CodeBehind="~/App_Code/Service.cs"
  %>

There is no customized ServiceHostFactory

9.To complete the example here is service.cs

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode =
        AspNetCompatibilityRequirementsMode.Required)]

public class Service
{
  //.............
}

Have fun

Tags:

This entry was posted on Monday, November 29th, 2010 at 6:38 am and is filed under ASP.NET. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

*