Monday, May 14, 2007

Hosting WCF Service in IIS with WAS (Windows Activation Service)

WCF allows to host the services in serval ways. Every scenario has it specific advantages and it is important to choose the right way to host your processes. The options for hosting are to host in IIS, an executable or a service.

Before Vista it was possible to host only webservices or remoting via HTTP in IIS because there was the limitation till IIS 6.0 that the communcation protocol had to be HTTP(s). It is mentioned in the MSDN that you can actually use WAS without IIS but till now I could not find any sample where this is explained.

The main complexity of hosting in IIS is to set up your IIS to allow TCP/IP for for the server and for the specific webapplication. The steps to get started are to install the WCF Non-HTTP activation components. To do that, go to the Start menu —> Control Panel —> Programs and Features, and then click "Turn Windows Components On or Off" in the left pane. Expand the Microsoft .NET Framework 3.0 node and ensure that the "Windows Communication Foundation Non-HTTP Activation" feature is checked.

Secondly run the following command as Administrator.
c:\windows\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

Then a new application needs to be created in IIS. In this case I created the TestApp2 application. After creating it it is important to apply the following statement as Administrator.
C:\Windows\System32\inetsrv\appcmd.exe set app "Default Web Site/TestApp2" /enabled Protocols:http,net.tcp.

This makes sure that the application is also accessable via TCP/IP.

Now IIS has been set up to host components. The next step is to create a new project in Visual Studio 2005 of the type WCF Service Library and then remove all the commented text.

To keep the service as simple as possible I made the following implentation.

[ServiceContract()]
public interface IMyService
{
[OperationContract]
string SayHello(string value);
}

public class MyService : IMyService
{
public string SayHello(string value)
{
return "Hello " + value;
}
}

Then two files need to be added. The first one is the definition of the service. This must exist in a file with the extention svc and will be the entry point for IIS to the service. The file in this example is called Service.svc and the content of the file is
<% @ServiceHost Language=C# Debug="true" Service="MyService" %>
The next file that needs to be added is the Web.Config. One of the main things in the Web.Config file is the declaration of the IMetadataExchange contact. This allows to exchange the meta information over TCP/IP.


<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
contract="IMyService" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="PortSharingBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings> <behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>


Compile the service and then copy the files web.config and service.svc over to the folder that corresponds with the application you previosly created. In this example it is c:\inetpub\wwwroot\TestApp2. And create the folder Bin where the dll is copied.
The service is not created and can be accessed over TCP/IP. This means that it can possible to check if the methods exist using the Internet Browser.

The client can be either type of application and the reference needs to be set to
net.tcp://localhost/TestApp2/Service.svc. The service proxy is automatically created and can be accessed equalty to any WCF Service.

3 comments:

Anonymous said...

I have a singelton WCF under an IIS 7 application. I can invoke it manually through a browser just fine and have the constructor execute, etc.
However, how would I go about setting it up so that the service is automatically started (i.e. constructed) upon IIS or application pool restart??

Cheers,
Mike B.

Unknown said...

Hi.....I am really impressed by your post the way in which you have written the article and bring those points to my attention are really amazing. Good work. Thanks.
dedicated web hosting

Anonymous said...

Great work ...How much time I wasted to make the TCP ip bindings to work with the WEbDAV(cassini) ..For some reason it never works with it..
Then I turned to IIS and found ur post..Hosted the stuff...