”;
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:Windowssystem32inetsrv> 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:Windowssystem32inetsrvconfig” 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 WindowsMicrosoft.NetFrameworkvx.xConfig --> <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:Windowssystem32inetsrv>appcmd set app "Default Web Site/WASHostedService" /enabledProtocols:http,net.tcp
It will produce the following output −
”;