WCF - WAS Hosting


Advertisements


To understand the concept of WAS hosting, we need to comprehend how a system is configured and how a service contract is created, enabling different binding to the hosted service.

First of all, enable WCF for non-protocols. Before we start creating the service, we need to configure the system to support WAS. Following are the steps to configure WAS −

  • Click Start Menu → Control Panel → Programs and Features, and click "Turn Windows Components On or Off" in the left pane.

  • Expand "Microsoft .Net Framework 3.0" and enable "Windows Communication Foundation HTTP Activation" and "Windows Communication Foundation Non- HTTP Activation".

  • Next, we need to add Binding to the default website. As an example, we will bind the default website to the TCP protocol. Go to Start Menu → Programs → Accessories. Right click on the "Command Prompt", and select "Run as administrator" from the context menu.

  • Execute the following command −

C:\Windows\system32\inetsrv> appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

This command adds the net.tcp site binding to the default website by modifying the applicationHost.config file located in the "C:\Windows\system32\inetsrv\config" directory. Similarly, we can add different protocols to the default website.

Create WAS Hosted Service

Step-1 − Open Visual Studio 2008 and click New → WebSite and select WCF Service from the template and Location as HTTP, as shown below −

Wcf Hosting Services WAS 1

Step-2 − Create the Contract by creating an interface IMathService. Add the ServiceContract attribute to the interface and the OperationContract attribute to the method declaration.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the interface name "IService" in both code and config file 
// together.

[ServiceContract]

Public interface IMathService {
  [OperationContract]
  int Add(int num1, int num2);

  [OperationContract]
  int Subtract(int num1, int num2);
} 

Step-3 − The implementation of the IMathService interface is shown below −

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the class name "Service" in code, svc and config file 
// together.

Public class MathService : IMathService {
   Public int Add(int num1, int num2) {
      return num1 + num2;
   }

   Public int Subtract(int num1, int num2) {
      return num1 - num2;
   }
}

Step-4 − The Service file is shown below.

Wcf Hosting Services WAS 2

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

Step-5 − In the web.Config file, create endpoint with 'netTcpBinding' binding and the service metadata will be published using the Metadata Exchange point. So create the Metadata Exchange end-point with the address as 'mex' and the binding as 'mexTcpBinding'. Without publishing the service metadata, we cannot create the proxy using the net.tcp address, for example -

svcutil.exe net.tcp://localhost/WASHostedService/MathService.svc).
<?xml version="1.0" ?>
<configuration>
   <!--
      Note: As an alternative to hand editing this file you can use the 
         web admin tool to configure settings for your application. Use
         the Website->Asp.Net Configuration option in Visual Studio.
         A full list of settings and comments can be found in 
         machine.config.comments usually located in 
         \Windows\Microsoft.Net\Framework\vx.x\Config 
   -->
   <configSections>
      <sectionGroup name="system.web.extensions" 
         type="System.Web.Configuration.SystemWebExtensionsSectionGroup, 
         System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
         PublicKeyToken=31BF3856AD364E35">
		
         <sectionGroup name="scripting" 
            type="System.Web.Configuration.ScriptingSectionGroup, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35">

            <section name="scriptResourceHandler" 
               type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, 
               System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
               PublicKeyToken=31BF3856AD364E35" 
               requirePermission="false" 
               allowDefinition="MachineToApplication"/>

            <sectionGroup name="webServices" 
               type="System.Web.Configuration.ScriptingWebServicesSectionGroup, 
               System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
               PublicKeyToken=31BF3856AD364E35">

               <section name="jsonSerialization" 
                  type="System.Web.Configuration.ScriptingJsonSerializationSection, 
                  System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
                  PublicKeyToken=31BF3856AD364E35" requirePermission="false" 
                  allowDefinition="Everywhere"/>

               <section name="profileService" 		     
                  type="System.Web.Configuration.ScriptingProfileServiceSection, 
                  System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
                  PublicKeyToken=31BF3856AD364E35" requirePermission="false" 
                  allowDefinition="MachineToApplication"/>

               <section name="authenticationService" 			     
                  type="System.Web.Configuration.ScriptingAuthenticationServiceSection, 
                  System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
                  PublicKeyToken=31BF3856AD364E35" requirePermission="false" 
                  allowDefinition="MachineToApplication"/>

               <section name="roleService"	
                  type="System.Web.Configuration.ScriptingRoleServiceSection, 
                  System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
                  PublicKeyToken=31BF3856AD364E35" requirePermission="false"
                  allowDefinition="MachineToApplication"/>

            </sectionGroup>
         </sectionGroup>
      </sectionGroup>
   </configSections>
   
   <appSettings/>
   <connectionStrings/>
   
   <system.web>
      <!--
      Set compilation debug="true" to insert debugging 
      symbols into the compiled page. Because this 
      affects performance, set this value to true only 
      during development.
      -->
      <compilation debug="true">
         <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, 
               Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            
            <add assembly="System.Web.Extensions, Version=3.5.0.0, 
               Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
            <add assembly="System.Data.DataSetExtensions, 
               Version=3.5.0.0, Culture=neutral,                  
               PublicKeyToken=B77A5C561934E089"/>
            
            <add assembly="System.Web.Extensions, Version=3.5.0.0, 
               Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
            <add assembly="System.Xml.Linq, 
               Version=3.5.0.0, Culture=neutral, 
               PublicKeyToken=B77A5C561934E089"/>
         </assemblies>
      </compilation>
      
      <!--
      The <authentication> section enables configuration          
      of the security authentication mode used by 
      ASP.NET to identify an incoming user. 
      -->
      
      <authentication mode="Windows"/>
      
      <!--
      The <customErrors> section enables configuration 
      of what to do if/when an unhandled error occurs 
      during the execution of a request. Specifically, 
      it enables developers to configure html error pages 
      to be displayed in place of a error stack trace.
      <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
      <error statusCode="403" redirect="NoAccess.htm" />
      <error statusCode="404" redirect="FileNotFound.htm" />
      </customErrors>
      -->
      
      <pages>
         <controls>
            <add tagPrefix="asp" namespace="System.Web.UI" 
               assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
               PublicKeyToken=31BF3856AD364E35"/>
            
            <add tagPrefix="asp" namespace="System.Web.UI.WebControls"
               assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
               PublicKeyToken=31BF3856AD364E35"/>
         </controls>
      </pages>
      
      <httpHandlers>
         <remove verb="*" path="*.asmx"/>
         
         <add verb="*" path="*.asmx" validate="false"         
            type="System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
         
         <add verb="*" path="*_AppService.axd" validate="false" 
            type="System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, 
            Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
         
         <add verb="GET,HEAD" path="ScriptResource.axd"        
            type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, 
            Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35" validate="false"/>
         
      </httpHandlers>
      
      <httpModules>
         <add name="ScriptModule" 
            type="System.Web.Handlers.ScriptModule, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
      </httpModules>
      
   </system.web>
   
   <system.codedom>
      <compilers>
         <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" 
            type="Microsoft.CSharp.CSharpCodeProvider, System, 
            Version=2.0.0.0, Culture=neutral,                 
            PublicKeyToken=b77a5c561934e089">
         
            <providerOption name="CompilerVersion" value="v3.5"/>
            <providerOption name="WarnAsError" value="false"/>
            
         </compiler>
         
         <compiler language="vb;vbs;visualbasic;vbscript" 
            extension=".vb" warningLevel="4" 
            type="Microsoft.VisualBasic.VBCodeProvider, System, 
            Version=2.0.0.0, Culture=neutral,                  
            PublicKeyToken=b77a5c561934e089">
         
            <providerOption name="CompilerVersion" value="v3.5"/>
            <providerOption name="OptionInfer" value="true"/>
            <providerOption name="WarnAsError" value="false"/>
            
         </compiler>
      </compilers>
   </system.codedom>
   
   <!--     The system.webServer section is required for running ASP.NET AJAX under 
   Internet Information Services 7.0. It is not necessary for previous version of IIS.
   -->
   
   <system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      
      <modules>
         <remove name="ScriptModule"/>
         <add name="ScriptModule" preCondition="managedHandler"         
            type="System.Web.Handlers.ScriptModule, System.Web.Extensions, 
            Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
      </modules>
      
      <handlers>
         <remove name="WebServiceHandlerFactory-Integrated"/>
         <remove name="ScriptHandlerFactory"/>
         <remove name="ScriptHandlerFactoryAppServices"/>
         <remove name="ScriptResource"/>
         
         <add name="ScriptHandlerFactory" 
            verb="*" path="*.asmx" preCondition="integratedMode"              
            type="System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
         
         <add name="ScriptHandlerFactoryAppServices" 
            verb="*" path="*_AppService.axd" preCondition="integratedMode" 
            type="System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
         
         <add name="ScriptResource" preCondition="integratedMode" 
            verb="GET,HEAD" path="ScriptResource.axd" 
            type="System.Web.Handlers.ScriptResourceHandler, 
            System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
            PublicKeyToken=31BF3856AD364E35"/>
         
      </handlers>
      <!--
      To browse web app root directory during debugging, set the value below to true. 
      Set to false before deployment to avoid disclosing web app folder information.
      -->
      <directoryBrowse enabled="true"/>
   </system.webServer>
   
   <runtime>
      <assemblyBinding appliesTo="v2.0.05727"     xmlns="urn:schemas-microsoft-com:asm.v1">
      
         <dependentAssembly>
            <assemblyIdentity name="System.Web.Extensions"    publicKeyToken="31bf3856ad364e35"/>
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
         </dependentAssembly>
         
         <dependentAssembly>
            <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
         </dependentAssembly>
         
      </assemblyBinding>
   </runtime>
   
   <system.serviceModel>
      <services>
         <service behaviorConfiguration="ServiceBehavior" name="Service">
            <endpoint address="" binding="basicHttpBinding" contract="IMathService">
            
            <identity>
               <dns value="localhost" />
            </identity>
            
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
         </service>
      </services>
      
      <behaviors>
         <serviceBehaviors>
            <behavior name="ServiceBehavior">
               <!-- 
               To avoid disclosing metadata information, set the value below 
               to false before deployment. 
               -->
               <serviceMetadata httpGetEnabled="true"/>
               <!-- To receive exception details in faults for debugging purposes, 
                  set the value below to true. Set to false before deployment to avoid 
                  disclosing exception information 
               -->
               <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
         </serviceBehaviors>
      </behaviors>
      
   </system.serviceModel>
</configuration>

Enable Different Bindings to the Hosted Service

  • Go to Start menu → Programs → Accessories. Right click on the "Command Prompt", and select "Run as administrator" from the context menu.

  • Execute the following command -

C:\Windows\system32\inetsrv>appcmd set app "Default Web Site/WASHostedService" /enabledProtocols:http,net.tcp

It will produce the following output −

Wcf Hosting Services WAS 6

Advertisements
E-Books Store