- WCF - Home
- WCF - Overview
- WCF - Versus Web Service
- WCF - Developers Tools
- WCF - Architecture
- WCF - Creating WCF Service
- WCF - Hosting WCF Service
- WCS - IIS Hosting
- WCF - Self-Hosting
- WCF - WAS Hosting
- WCF - Windows Service Hosting
- WCF - Consuming WCF Service
- WCF - Service Binding
- WCF - Instance Management
- WCF - Transactions
- WCF - RIA Services
- WCF - Security
- WCF - Exception Handling
WCF - WAS Hosting
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 −
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.
<%@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 =3 1BF3856AD364E35">
<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 −