WCF - Hospedagem WAS
Para entender o conceito de hospedagem WAS, precisamos compreender como um sistema é configurado e como um contrato de serviço é criado, permitindo ligações diferentes para o serviço hospedado.
Em primeiro lugar, habilite o WCF para não protocolos. Antes de começarmos a criar o serviço, precisamos configurar o sistema para oferecer suporte ao WAS. A seguir estão as etapas para configurar o WAS -
Clique em Menu Iniciar → Painel de controle → Programas e recursos e clique em "Ativar ou desativar componentes do Windows" no painel esquerdo.
Expanda "Microsoft .Net Framework 3.0" e habilite "Ativação HTTP do Windows Communication Foundation" e "Ativação não HTTP do Windows Communication Foundation".
Em seguida, precisamos adicionar Binding ao site padrão. Como exemplo, vincularemos o site padrão ao protocolo TCP. Vá para o menu Iniciar → Programas → Acessórios. Clique com o botão direito do mouse em "Prompt de comando" e selecione "Executar como administrador" no menu de contexto.
Execute o seguinte comando -
C:\Windows\system32\inetsrv> appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']
Este comando adiciona a ligação do site net.tcp ao site padrão, modificando o arquivo applicationHost.config localizado no diretório "C: \ Windows \ system32 \ inetsrv \ config". Da mesma forma, podemos adicionar protocolos diferentes ao site padrão.
Criar serviço hospedado WAS
Step-1 - Abra o Visual Studio 2008 e clique em Novo → WebSite e selecione Serviço WCF no modelo e Local como HTTP, conforme mostrado abaixo -
Step-2- Crie o contrato criando uma interface IMathService. Adicione o atributo ServiceContract à interface e o atributo OperationContract à declaração do método.
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 - A implementação da interface IMathService é mostrada abaixo -
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 - O arquivo de serviço é mostrado abaixo.
<%@ServiceHostLanguage="C#"Debug="true"Service="MathService"CodeBehind="~/App_Code/MathService.cs"%>
Step-5- No arquivo web.Config, crie um endpoint com ligação 'netTcpBinding' e os metadados do serviço serão publicados usando o ponto de troca de metadados. Portanto, crie o ponto de extremidade do Metadata Exchange com o endereço como 'mex' e a ligação como 'mexTcpBinding'. Sem publicar os metadados do serviço, não podemos criar o proxy usando o endereço net.tcp, por exemplo -
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>
Habilitar ligações diferentes para o serviço hospedado
Vá para o menu Iniciar → Programas → Acessórios. Clique com o botão direito do mouse em "Prompt de comando" e selecione "Executar como administrador" no menu de contexto.
Execute o seguinte comando -
C:\Windows\system32\inetsrv>appcmd set app "Default Web Site/WASHostedService" /enabledProtocols:http,net.tcp
Ele produzirá a seguinte saída -