WCF - Guia Rápido

WCF significa Windows Communication Foundation. O recurso básico do WCF é a interoperabilidade. É uma das tecnologias mais recentes da Microsoft, usada para construir aplicativos orientados a serviços. Com base no conceito de comunicação baseada em mensagem, em que uma solicitação HTTP é representada de maneira uniforme, o WCF torna possível ter uma API unificada independentemente dos diversos mecanismos de transporte.

O WCF foi lançado pela primeira vez em 2006 como parte da estrutura .NET com o Windows Vista e, em seguida, foi atualizado várias vezes. WCF 4.5 é a versão mais recente que agora é amplamente usada.

Um aplicativo WCF consiste em três componentes -

  • Serviço WCF,
  • Host de serviço WCF e
  • Cliente de serviço WCF.

A plataforma WCF também é conhecida como Modelo de Serviço.

Conceitos Fundamentais do WCF

mensagem

Esta é uma unidade de comunicação composta por várias partes além do corpo. As instâncias de mensagens são enviadas e recebidas para todos os tipos de comunicação entre o cliente e o serviço.

Endpoint

Ele define o endereço onde uma mensagem deve ser enviada ou recebida. Ele também especifica o mecanismo de comunicação para descrever como as mensagens serão enviadas junto com a definição do conjunto de mensagens. A estrutura de um ponto de extremidade compreende as seguintes partes -

Endereço

O endereço especifica o local exato para receber as mensagens e é especificado como um URI (Uniform Resource Identifier). É expresso como esquema: // domínio [: porta] / [caminho]. Dê uma olhada no endereço mencionado abaixo -

net.tcp: // localhost: 9000 / ServiceA

Aqui, 'net.tcp' é o esquema para o protocolo TCP. O domínio é 'localhost', que pode ser o nome de uma máquina ou domínio da web, e o caminho é 'ServiceA'.

Obrigatório

Ele define a maneira como um terminal se comunica. É composto por alguns elementos de ligação que constituem a infraestrutura de comunicação. Por exemplo, uma ligação indica os protocolos usados ​​para transporte, como TCP, HTTP, etc., o formato da codificação da mensagem e os protocolos relacionados à segurança e à confiabilidade.

Contratos

É uma coleção de operações que especifica qual funcionalidade o terminal expõe ao cliente. Geralmente consiste em um nome de interface.

Hospedagem

Hospedagem do ponto de vista do WCF refere-se à hospedagem do serviço WCF, que pode ser feita por meio de muitas opções disponíveis, como hospedagem própria, hospedagem IIS e hospedagem WAS.

Metadados

Esse é um conceito significativo do WCF, pois facilita a interação entre um aplicativo cliente e um serviço WCF. Normalmente, os metadados para um serviço WCF são gerados automaticamente quando habilitados e isso é feito pela inspeção do serviço e seus terminais.

Cliente WCF

Um aplicativo cliente criado para expor as operações de serviço na forma de métodos é conhecido como cliente WCF. Isso pode ser hospedado por qualquer aplicativo, mesmo aquele que presta serviços de hospedagem.

Canal

Canal é um meio pelo qual um cliente se comunica com um serviço. Diferentes tipos de canais são empilhados e são conhecidos como Pilhas de Canais.

SABONETE

Embora denominado como 'Protocolo de Acesso a Objetos Simples', o SOAP não é um protocolo de transporte; em vez disso, é um documento XML composto por uma seção de cabeçalho e corpo.

Vantagens do WCF

  • É interoperável com relação a outros serviços. Isso está em nítido contraste com o .NET Remoting, em que tanto o cliente quanto o serviço devem ter .Net.

  • Os serviços WCF oferecem maior confiabilidade e segurança em comparação com os serviços da Web ASMX (Active Server Methods).

  • Implementar o modelo de segurança e alterar a vinculação no WCF não exige uma grande mudança na codificação. Apenas algumas mudanças de configuração são necessárias para atender às restrições.

  • O WCF tem um mecanismo de registro integrado, enquanto em outras tecnologias, é essencial fazer a codificação necessária.

  • WCF integrou AJAX e suporte para JSON (JavaScript object notation).

  • Ele oferece escalabilidade e suporte para os padrões de serviço da Web futuros.

  • Possui um mecanismo de segurança padrão extremamente robusto.

Existem algumas diferenças importantes entre o WCF e um serviço da Web, listadas abaixo.

  • Attributes - O serviço WCF é definido pelos atributos ServiceContract e OperationContract, enquanto um serviço da web é definido pelos atributos WebService e WebMethod.

  • Protocols - O WCF oferece suporte a uma variedade de protocolos, ou seja, HTTP, Pipes nomeados, TCP e MSMQ, enquanto um serviço da Web oferece suporte apenas ao protocolo HTTP.

  • Hosting Mechanisms - Existem vários mecanismos de ativação para hospedagem WCF, ou seja, IIS (Internet Information Service), WAS (Windows Activation Service), Self-hosting e Windows Service, mas um serviço web é hospedado apenas pelo IIS.

  • Services - O WCF oferece suporte a uma segurança robusta, sistema de mensagens confiável, transação e interoperabilidade, enquanto um serviço da Web oferece suporte apenas a serviços de segurança.

  • Serializer - O WCF oferece suporte ao serializador DataContract, empregando System.Runtime.Serialization, enquanto um serviço da Web oferece suporte ao serializador XML usando System.Xml.Serialization.

  • Tools - A ferramenta ServiceMetadata (svcutil.exe) é usada para geração de cliente para um serviço WCF, enquanto a ferramenta WSDL.EXE é usada para gerar o mesmo para um serviço da web.

  • Exception Handling- No WCF, as exceções não tratadas são tratadas de uma maneira melhor com o uso de FaultContract. Eles não retornam ao cliente como em um serviço da web como falhas de SOAP.

  • Hash Table - É possível serializar uma tabela de hash no WCF, mas não é o caso em um serviço web.

  • Bindings - O WCF oferece suporte a vários tipos de ligações, como BasicHttpBinding, WSDualHttpBinding, WSHttpBinding, etc., enquanto um serviço da web oferece suporte apenas a SOAP ou XML.

  • Multithreading - O WCF oferece suporte a multithreading usando a classe ServiceBehavior, embora isso não seja compatível com um serviço da web.

  • Duplex Service Operations - O WCF oferece suporte a operações de serviço duplex além de oferecer suporte a operações de serviço unilateral e de solicitação-resposta, enquanto um serviço da Web não oferece suporte a operações de serviço duplex.

Para desenvolver um aplicativo de serviço WCF, existem principalmente duas ferramentas - Microsoft Visual Studio e CodePlex. O Microsoft Visual Studio é um pacote completo de ferramentas de desenvolvimento, necessárias para o desenvolvimento de um grande número de aplicativos diversos, como aplicativos da Web ASP.NET, aplicativos de desktop, aplicativos móveis e muitos mais.

O Microsoft Visual Studio usa a funcionalidade do .NET Framework. O CodePlex, por outro lado, é um site de hospedagem de projetos de código aberto da Microsoft que oferece várias ferramentas gratuitas para o desenvolvimento de aplicativos de serviço WCF.

Microsoft Visual Studio

Existem muitas edições do Microsoft Visual Studio e, inicialmente, ele (Visual Studio 2005) não era um defensor fervoroso do desenvolvimento do WCF. No momento, o Visual Studio 2008 é o único IDE da Microsoft disponível para o desenvolvimento de aplicativos de serviço WCF.

Hoje em dia, a versão mais recente do Microsoft Visual Studio 2010 também é uma ferramenta preferida para o desenvolvimento de aplicativos de serviço WCF. Há também um modelo pronto no Visual Studio para o desenvolvimento de aplicativos de serviço WCF.

A seleção de tal modelo leva à adição de arquivos para os seguintes fins -

  • Contrato de serviço
  • Implementação de serviço
  • Configuração de serviço

Os atributos de requisitos são adicionados automaticamente e um serviço "Hello World" simples é criado pelo Microsoft Visual Studio, mesmo sem escrever nenhum código.

CodePlex

O CodePlex foi lançado pela Microsoft em junho de 2006 e, desde então, tem sido usado por um grande número de desenvolvedores em todo o mundo para criar projetos .NET com sucesso. Algumas das ferramentas oferecidas pelo CodePlex para desenvolver aplicativos de serviço WCF são as seguintes -

  • wscf.blue- Este é um complemento do Microsoft Visual Studio e também um conjunto de ferramentas de desenvolvimento "primeiro de contrato" que facilita a definição das operações de serviço WCF e a geração de um esqueleto de código de acordo. Um link importante para o mesmo é -https://wscfblue.codeplex.com

  • WCFProxyGenerator- Este também é um suplemento do Microsoft Visual Studio. A ferramenta é usada para estender a geração do lado do cliente e oferecer tratamento de erros adicional. Para obter mais informações sobre esta ferramenta de desenvolvimento específica, visitehttps://wcfproxygenerator.codeplex.com

  • WCFMock- O teste de serviço WCF pode ser uma tarefa complicada e esta ferramenta de desenvolvimento oferece uma solução conveniente para o teste de unidade de serviços WCF por suas classes úteis. Para obter mais informações sobre esta ferramenta, visitehttps://wcfmock.codeplex.com

Outra ferramenta gratuita para o desenvolvimento de aplicativos de serviço WCF de maneira fácil é o WCFStorm. Sua versão LITE oferece muitos recursos impressionantes para invocar e testar serviços WCF dinamicamente, editar a vinculação do serviço, modificar o endpoint de URL do WCF, etc.

O WCF tem uma arquitetura em camadas que oferece amplo suporte para o desenvolvimento de vários aplicativos distribuídos. A arquitetura é explicada em detalhes a seguir.

Contratos

A camada de contratos está logo ao lado da camada de aplicativo e contém informações semelhantes às de um contrato do mundo real que especifica a operação de um serviço e o tipo de informação acessível que ele fará. Os contratos são basicamente de quatro tipos discutidos abaixo em breve -

  • Service contract - Este contrato fornece informações ao cliente, bem como ao mundo exterior, sobre as ofertas do terminal e os protocolos a serem usados ​​no processo de comunicação.

  • Data contract- Os dados trocados por um serviço são definidos por um contrato de dados. Tanto o cliente quanto o serviço devem estar de acordo com o contrato de dados.

  • Message contract- Um contrato de dados é controlado por um contrato de mensagem. Ele faz principalmente a customização da formatação de tipo dos parâmetros de mensagem SOAP. Aqui, deve ser mencionado que o WCF emprega o formato SOAP para fins de comunicação. SOAP significa Simple Object Access Protocol.

  • Policy and Binding- Existem certas condições prévias para a comunicação com um serviço, e tais condições são definidas por política e contrato vinculativo. Um cliente precisa seguir este contrato.

Tempo de execução do serviço

A camada de tempo de execução do serviço está logo abaixo da camada de contratos. Ele especifica os vários comportamentos de serviço que ocorrem durante o tempo de execução. Existem muitos tipos de comportamento que podem sofrer configuração e entrar no tempo de execução do serviço.

  • Throttling Behavior - Gerencia o número de mensagens processadas.

  • Error Behavior - Define o resultado de qualquer ocorrência de erro interno do serviço.

  • Metadata Behavior - Especifica a disponibilidade de metadados para o mundo externo.

  • Instance Behavior - Define o número de instâncias que precisam ser criadas para disponibilizá-las para o cliente.

  • Transaction Behavior - Permite uma mudança no estado da transação em caso de qualquer falha.

  • Dispatch Behavior - Controla a forma como uma mensagem é processada pela infraestrutura do WCF.

  • Concurrency Behavior - Controla as funções que funcionam paralelamente durante uma comunicação cliente-servidor.

  • Parameter Filtering - Apresenta o processo de validação de parâmetros para um método antes de ser invocado.

Mensagens

Essa camada, composta por diversos canais, trata principalmente do conteúdo da mensagem a ser comunicada entre dois terminais. Um conjunto de canais forma uma pilha de canais e os dois principais tipos de canais que compõem a pilha de canais são os seguintes -

  • Transport Channels - Esses canais estão presentes na parte inferior de uma pilha e são responsáveis ​​pelo envio e recebimento de mensagens usando protocolos de transporte como HTTP, TCP, Ponto a Ponto, Pipes Nomeados e MSMQ.

  • Protocol Channels - Presentes no topo de uma pilha, esses canais também conhecidos como canais em camadas, implementam protocolos de nível de fio modificando mensagens.

Ativação e Hospedagem

A última camada da arquitetura WCF é o local onde os serviços são realmente hospedados ou podem ser executados para fácil acesso pelo cliente. Isso é feito por vários mecanismos discutidos abaixo em breve.

  • IIS- IIS significa Internet Information Service. Ele oferece uma infinidade de vantagens ao usar o protocolo HTTP por um serviço. Aqui, não é necessário ter o código do host para ativar o código do serviço; em vez disso, o código de serviço é ativado automaticamente.

  • Windows Activation Service- Isso é conhecido popularmente como WAS e vem com o IIS 7.0. A comunicação baseada em HTTP e não HTTP é possível aqui usando os protocolos TCP ou Namedpipe.

  • Self-hosting- Este é um mecanismo pelo qual um serviço WCF fica auto-hospedado como um aplicativo de console. Esse mecanismo oferece uma flexibilidade incrível em termos de escolha dos protocolos desejados e configuração do próprio esquema de endereçamento.

  • Windows Service - Hospedar um serviço WCF com este mecanismo é vantajoso, pois os serviços então permanecem ativados e acessíveis ao cliente devido a nenhuma ativação em tempo de execução.

Criar um serviço WCF é uma tarefa simples usando o Microsoft Visual Studio 2012. Abaixo está o método passo a passo para criar um serviço WCF junto com toda a codificação necessária, para entender o conceito de uma maneira melhor.

  • Inicie o Visual Studio 2012.
  • Clique no novo projeto e, em seguida, na guia Visual C #, selecione a opção WCF.

É criado um serviço WCF que executa operações aritméticas básicas como adição, subtração, multiplicação e divisão. O código principal está em dois arquivos diferentes - uma interface e uma classe.

Um WCF contém uma ou mais interfaces e suas classes implementadas.

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

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

   [ServiceContract]
   Public interface IService1 {
      [OperationContract]
      int sum(int num1, int num2);

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

      [OperationContract]
      int Multiply(int num1, int num2);

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

   // Use a data contract as illustrated in the sample below to add 
   // composite types to service operations.

   [DataContract]
   Public class CompositeType {
      Bool boolValue = true;
      String stringValue = "Hello ";

      [DataMember]
      Public bool BoolValue {
         get { return boolValue; }
         set { boolValue = value; }
      }

      [DataMember]   
      Public string StringValue {
         get { return stringValue; }
         set { stringValue = value; }
      }
   }
}

O código por trás de sua classe é fornecido abaixo.

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

namespace WcfServiceLibrary1 {
   // NOTE: You can use the "Rename" command on the "Refactor" menu to 
   // change the class name "Service1" in both code and config file 
   // together.

   publicclassService1 :IService1 {
      // This Function Returns summation of two integer numbers
      
      publicint sum(int num1, int num2) {
         return num1 + num2;
      }
      
      // This function returns subtraction of two numbers. 
      // If num1 is smaller than number two then this function returns 0
      
      publicint Subtract(int num1, int num2) {
         if (num1 > num2) {
            return num1 - num2;
         }
         else {
            return 0;
         }
      }
      
      // This function returns multiplication of two integer numbers.
      publicint Multiply(int num1, int num2) {
         return num1 * num2;
      }
      
      // This function returns integer value of two integer number. 
      // If num2 is 0 then this function returns 1.
      publicint Divide(int num1, int num2) {
         if (num2 != 0) {
            return (num1 / num2);
         } else {
            return 1;
         }
      }
   }
}

Para executar este serviço, clique no botão Iniciar no Visual Studio.

Enquanto executamos este serviço, a seguinte tela aparece.

Ao clicar no método de soma, a seguinte página é aberta. Aqui, você pode inserir quaisquer dois números inteiros e clicar no botão Chamar. O serviço retornará a soma desses dois números.

Como a soma, podemos realizar todas as outras operações aritméticas listadas no menu. E aqui estão as fotos para eles.

A página a seguir aparece ao clicar no método Subtrair. Insira os números inteiros, clique no botão Chamar e obtenha a saída conforme mostrado aqui -

A página a seguir aparece ao clicar no método Multiply. Insira os números inteiros, clique no botão Chamar e obtenha a saída conforme mostrado aqui -

A página a seguir aparece ao clicar no método Divide. Insira os números inteiros, clique no botão Chamar e obtenha a saída conforme mostrado aqui -

Depois que o serviço é chamado, você pode alternar entre eles diretamente aqui.

Depois de criar um serviço WCF, a próxima etapa é hospedá-lo para que os aplicativos cliente possam consumi-lo. Isso é conhecido como hospedagem de serviço WCF. Um serviço WCF pode ser hospedado usando qualquer uma das quatro maneiras fornecidas abaixo -

  • IIS Hosting- IIS significa Internet Information Services. Seu modelo de trabalho é semelhante ao do ASP.NET enquanto hospeda um serviço WCF. O melhor recurso da hospedagem IIS é que a ativação do serviço é processada automaticamente. A hospedagem IIS também oferece monitoramento da integridade do processo, desligamento ocioso, reciclagem do processo e muitos outros recursos para facilitar a hospedagem do serviço WCF.

  • Self-Hosting- Quando um serviço WCF é hospedado em um aplicativo gerenciado, ele é conhecido como auto-hospedagem. Requer que um desenvolvedor escreva a codificação necessária para a inicialização do ServiceHost. Na auto-hospedagem, um serviço WCF pode ser hospedado em uma variedade de aplicativos, como aplicativo de console, formulário do Windows, etc.

  • WAS Hosting - Hospedar um serviço WCF no Windows Activation Service (WAS) é mais vantajoso por causa de seus recursos, como reciclagem de processos, gerenciamento de tempo ocioso, sistema de configuração comum e suporte para HTTP, TCP, etc.

  • Windows Service Hosting- Para clientes do sistema local, é melhor hospedar o serviço WCF como um serviço de janela e isso é conhecido como Hospedagem de serviço de janela. Todas as versões do Windows oferecem suporte a esse tipo de hospedagem e, aqui, o Service Control Manager pode controlar o ciclo de vida do processo do serviço WCF.

Hospedar um serviço WCF no IIS (Internet Information Services) é um processo passo a passo. A hospedagem IIS é ilustrada abaixo em detalhes com a codificação desejada, bem como capturas de tela para entender o processo.

Step 1- Inicie o Visual Studio 2012 e clique em Arquivo → Novo → Site. Selecione “Serviço WCF” e Local como http. Isso hospedará o serviço no IIS. Clique OK.

Step 2 - O código por trás da interface é fornecido 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 interface name "IService" in both code and config file 
// together.

[ServiceContract]
Public interface IService {
   [OperationContract]
   String GetData(int value);

   [OperationContract]
   CompositeType GetDataUsingDataContract(CompositeType composite);

   // TODO: Add your service operations here
}

// Use a data contract as illustrated in the sample below to add 
// composite types to service operations.

[DataContract]
Public class CompositeType {
   Bool boolValue = true;
   String stringValue = "Hello ";

   [DataMember]
   Public bool BoolValue {
      get { return boolValue; }
      set { boolValue = value; }
   }

   [DataMember]
   Public string StringValue {
      get { return stringValue; }
      set { stringValue = value; }
   }
}

Step 3 - O código por trás do arquivo de classe é fornecido 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 Service : IService {
   Public string GetData(int value) {
      Return string.Format("You entered: {0}", value);
   }

   Public CompositeType GetDataUsingDataContract(CompositeType composite) {
      if(composite == null) {
         thrownewArgumentNullException("composite");
      }
      
      if(composite.BoolValue) {
         composite.StringValue += "Suffix";
      }
      return composite;
   }
}

Step 4- Arquivo de serviço (.svc) contém o nome do serviço e o código por trás do nome do arquivo. Este arquivo é usado para saber sobre o serviço.

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

Step 5- As configurações do lado do servidor são mencionadas no arquivo de configuração. Aqui, há uma menção de apenas um ponto de extremidade configurado para 'wsHttpBinding'; também podemos ter vários pontos de extremidade com ligações diferentes. Como hospedaremos no IIS, precisamos usar apenas a vinculação http.

<?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"  
         ype = "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 name = "Service" behaviorConfiguration = "ServiceBehavior">
         <!-- Service Endpoints -->
            <endpoint address = "" binding = "basicHttpBinding" contract = "IService">
               <!-- 
                  Upon deployment, the following identity element should be removed or replaced 
                  to reflect the identity under which the deployed service runs. If removed, 
                  WCF will infer an appropriate identity automatically.
               -->

               <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 false avoid 
                  disclosing exception information -->
               
               <serviceDebug includeExceptionDetailInFaults = "false"/>
            </behavior>
         </serviceBehaviors>
      </behaviors>
      
   </system.serviceModel>
</configuration>

Step 6- Você precisa mencionar o nome do arquivo do serviço, junto com o endereço mencionado no arquivo de configuração. A captura de tela do IIS é fornecida aqui.

Clique em Iniciar → executar → inetmgr que abrirá a seguinte janela.

Step 7 - Execute o aplicativo que produzirá a seguinte tela.

Aqui, o serviço WCF é hospedado em um aplicativo de console. Dada a seguir é o processo com etapas adequadas de forma sequencial que explica todo o processo.

Step 1- Primeiro, vamos criar o contrato de serviço e sua implementação. Crie um aplicativo de console e nomeie-o como MyCalculatorService. Este é um serviço simples para retornar a adição de dois números.

Step 2- Agora, clique com o botão direito em References no Solution Explorer e clique em Add References. A seguinte janela é aberta; adicione a referência System.ServiceModel ao projeto.

Step 3- Crie uma interface ISimpleCalculator, adicione o atributo ServiceContract e OperationContract à classe e função conforme mostrado abaixo. Você saberá mais sobre esses contratos na sessão posterior. Esses contratos irão expor o método para o mundo externo para usar este serviço.

Step 4 - O código por trás deste arquivo é o seguinte -

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

namespace MyCalculatorWCFService {
   [ServiceContract()]
   Public interface ISimpleCalculator {
      [OperationContract()]
      int Add(int num1, int num2);
   }
}

Step 5 - MyCalculatorService é a classe de implementação para a interface IMyCalculatorService conforme mostrado abaixo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCalculatorWCFService {
   Class SimpleCalculator : ISimpleCalculator {
      Public int Add(int num1, int num2) {
         return num1 + num2;
      }
   }
}

Step 6- Agora estamos prontos com o serviço. Vamos implementar o processo de hospedagem. Crie um novo aplicativo de console e nomeie-o como 'MyCalculatorWCFServiceHost'.

Step 7 - Adicione a referência de system.servicemodel e o projeto MyCalculatorWCFService.

O código por trás disso é o seguinte -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyCalculatorWCFService;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace MyCalculatorWCFServiceHost {
   class Program {
      static void Main(string[] args) {
         //Create a URI to serve as the base address
         UrihttpUrl = newUri("http://localhost:8090/MyCalculatorWCFService/SimpleCalculator");
         
         //Create ServiceHost
         ServiceHost host = newServiceHost(typeof(MyCalculatorWCFService.ISimpleCalculator), httpUrl);
         
         //Add a service endpoint
         host.AddServiceEndpoint(typeof(MyCalculatorWCFService.ISimpleCal culator), newWSHttpBinding(), "");
         
         //Enable metadata exchange
         ServiceMetadataBehaviorsmb = newServiceMetadataBehavior();
         smb.HttpGetEnabled = true;
         host.Description.Behaviors.Add(smb);

         //Start the Service
         host.Open();
         Console.WriteLine("Service is host at " + DateTime.Now.ToString());
         Console.WriteLine("Host is running... Press  key to stop");
         Console.ReadLine();
      }
   }
}

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 ao 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 no 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 diferentes protocolos 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 a vinculaçã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 -

A operação de hospedagem de serviços do Windows é simples. Abaixo estão as etapas com a codificação necessária e capturas de tela que explicam o processo de uma maneira fácil.

Step 1- Agora vamos criar um serviço WCF. Abra o Visual Studio 2008 e clique em Novo → Projeto e selecione Biblioteca de classes no modelo.

Step 2- Adicione a referência System.ServiceModel ao projeto. Este é o assembly principal usado para criar o serviço WCF.

Step 3- Em seguida, podemos criar a interface ISimpleCalulator. Adicione o atributo Contrato de Serviço e Operação conforme mostrado abaixo -

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

namespace WindowsServiceHostedService{
   [ServiceContract]
   public interfaceISimpleCalculator {
      [OperationContract]
      int Add(int num1, int num2);

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

      [OperationContract]
      int Multiply(int num1, int num2);

      [OperationContract]
      double Divide(int num1, int num2);
   }
}

Step 4 - Implemente a interface ISimpleCalculator conforme mostrado abaixo -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsServiceHostedService {
   Class SimpleCalulator : ISimpleCalculator {
      Public int Add(int num1, int num2) {
         return num1 + num2;
      }
      Public int Subtract(int num1, int num2) {
         return num1 - num2;
      }
      Public int Multiply(int num1, int num2) {
         return num1 * num2;
      }
      Public double Divide(int num1, int num2) {
         if (num2 != 0)
            return num1 / num2;
         else
            return 0;
      }
   }
}

Step 5- Construa o projeto e obtenha a dll. Agora, estamos prontos com o serviço WCF. Veremos como hospedar o serviço WCF no serviço do Windows.

Note- Neste projeto, é mencionado que estamos criando contrato e serviço (implementação) no mesmo projeto. No entanto, é sempre uma boa prática se você tiver os dois em projetos diferentes.

Step 6 - Abra o Visual Studio 2008 e clique em Novo → Projeto e selecione Serviço do Windows.

Step 7- Adicione 'WindowsServiceHostedService.dll' como referência ao projeto. Esta assembleia vai funcionar como serviço.

Step 8- O método OnStart do serviço pode ser usado para escrever o código de hospedagem para o WCF. Precisamos ter certeza de que estamos usando apenas um objeto de host de serviço. O método OnStop é usado para fechar o Host de serviço. O código a seguir mostra como hospedar o serviço WCF no serviço do Windows.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCFHostedWindowsService {
   Partial class WCFHostedWindowsService : ServiceBase {
      ServiceHostm_Host;

      Public WCFHostedWindowsService() {
         InitializeComponent();
      }
      Private void InitializeComponent() {
         thrownewNotImplementedException();
      }
      protectedoverridevoidOnStart(string[] args) {
         if (m_Host != null) {
            m_Host.Close();
         }
        
         //Create a URI to serve as the base address
         UrihttpUrl = newUri("http://localhost:8090/WindowsServiceHostedService/SimpleCalculator");
        
         //Create ServiceHost
         m_Host = newServiceHost typeof(WindowsServiceHostedService.SimpleCalulator), httpUrl);
        
         //Add a service endpoint
         m_Host.AddServiceEndpoint (typeof(WindowsServiceHostedService.ISimpleCalculator), newWSHttpBinding(), "");
        
         //Enable metadata exchange
         ServiceMetadataBehaviorsmb = newServiceMetadataBehavior();
         smb.HttpGetEnabled = true;
         m_Host.Description.Behaviors.Add(smb);
        
         //Start the Service
         m_Host.Open();
      }
      protectedoverridevoidOnStop() {
         if (m_Host != null) {
            m_Host.Close();
            m_Host = null;
         }
      }
      staticvoid Main() {
         ServiceBase[] ServicesToRun;
         ServicesToRun = newServiceBase[] { 
            newWCFHostedWindowsService();
         }   
         ServiceBase.Run(ServicesToRun);
      }
   }
}

Step 9- Para instalar o serviço, precisamos ter a classe Installer para o serviço Windows. Portanto, adicione uma nova classe Installer ao projeto, que é herdada da classe Installer. A seguir está o código que mostra o nome do serviço, o tipo de inicialização, etc. do serviço.

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceProcess;
using System.Configuration.Install;
using System.ComponentModel;
using System.Configuration;

namespace WCFHostedWindowsService {
   [RunInstaller(true)]
   Public class WinServiceInstaller : Installer {
      Private ServiceProcessInstaller process;
      Private ServiceInstaller service;

      Public WinServiceInstaller() {
         process = newServiceProcessInstaller();
         process.Account = ServiceAccount.NetworkService;
         service = newServiceInstaller();
         
         service.ServiceName = "WCFHostedWindowsService";
         service.DisplayName = "WCFHostedWindowsService";
         service.Description = "WCF Service Hosted";
         service.StartType = ServiceStartMode.Automatic;
         
         Installers.Add(process);
         Installers.Add(service);
      }
   }
}

Step 10- Construa o projeto para obter o arquivo executável WCFHostedWindowsService.exe. Em seguida, precisamos instalar o serviço usando o Prompt de Comando do Visual Studio. Portanto, abra o prompt de comando clicando em Iniciar → Todos os programas → Microsoft Visual Studio 2008 → Ferramentas do Visual Studio → Prompt de comando do Visual Studio. Usando o aplicativo utilitário de instalação, você pode instalar o serviço conforme mostrado abaixo.

Os serviços WCF permitem que outros aplicativos os acessem ou os consumam. Um serviço WCF pode ser consumido de várias maneiras, dependendo do tipo de hospedagem. Aqui, estamos explicando o método passo a passo para consumir um serviço WCF para cada uma das seguintes opções de hospedagem populares -

  • Consumindo serviço WCF hospedado no IIS 5/6
  • Consumir serviço WCF que é auto-hospedado
  • Consumindo serviço WCF hospedado no Windows Activation Service
  • Consumindo serviço WCF hospedado no serviço Windows

Consumindo serviço WCF hospedado no IIS 5/6

O processo de consumo de um serviço WCF hospedado no IIS 5/6 é discutido abaixo em detalhes. Além disso, a discussão inclui como criar aplicativos de proxy e console.

Step 1- Depois que um serviço é hospedado no IIS, temos que consumi-lo nos aplicativos clientes. Antes de criar o aplicativo cliente, precisamos criar um proxy para o serviço. Este proxy é usado pelo aplicativo cliente para interagir com o serviço. Para criar um proxy, execute o prompt de comando do Visual Studio 2008. Usando o utilitário de serviço, podemos criar a classe de proxy e suas informações de configuração.

svcutilhttp: //localhost/IISHostedService/Service.svc

Após executar este comando, obteremos dois arquivos gerados no local padrão.

  • MyService.cs - Classe proxy para o serviço WCF

  • output.config - Informações de configuração sobre o serviço

Step 2 - Agora, vamos começar a criar o aplicativo Console usando o Visual Studio 2008 (aplicativo cliente).

Step 3- Adicione a referência 'System.ServiceModel'; esta é a dll principal do WCF.

Step 4 - Crie uma classe Proxy.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyServiceClient {
   Class Program {
      Static void Main(string[] args) {
         // Creating Proxy for the MyService
         ServiceClient Client = newServiceClient();
         Console.WriteLine("Client calling the service...");
         Console.WriteLine("Hello Ram");
         Console.Read();
      }
   }
}

A saída aparece da seguinte forma -

Consumindo serviço WCF auto-hospedado

Aqui, todo o processo de consumo de um serviço WCF auto-hospedado é explicado passo a passo junto com uma ampla codificação e capturas de tela sempre que necessário.

Step 1- O serviço está hospedado, agora precisamos implementar a classe proxy para o cliente. Existem diferentes maneiras de criar o proxy.

  • Usando SvcUtil.exe, podemos criar a classe de proxy e seu arquivo de configuração com pontos de extremidade.

  • Adicionando referência de serviço ao aplicativo cliente.

  • Implementando a classe ClientBase <T>

Destes três métodos, Implementing ClientBase <T> é a prática recomendada. Se você estiver usando os outros dois métodos, precisaremos criar uma classe de proxy sempre que fizermos qualquer alteração na implementação do Serviço. Mas este não é o caso de ClientBase <T>. Ele criará o proxy apenas em tempo de execução e, portanto, cuidará de tudo.

Para isso, crie uma classe de proxy, que inclui as referências de System.ServiceModel e MyCalculatorService.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorService;

namespace MyCalculatorServiceProxy {
   // WCF create proxy for ISimpleCalculator using ClientBase
   Public class MyCalculatorServiceProxy : 
   ClientBase<ISimpleCalculator>,
   
   ISimpleCalculator {
      Public int Add(int num1, int num2) {
         //Call base to do funtion
         returnbase.Channel.Add(num1, num2);
      }
   }
}

Agora, crie um aplicativo de console, que inclui as referências de System.ServiceModel e MyCalculatorServiceProxy.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorServiceProxy;

namespace MyCalculatorServiceClient {
   classProgram {
      Static void Main(string[] args) {
         MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy = newMyCalculatorServiceProxy.MyCalculatorServiceProxy();
         
         Console.WriteLine("Client is running at " + DateTime.Now.ToString());
         Console.WriteLine("Sum of two numbers. 5 + 5 =" + proxy.Add(5,5));
         Console.ReadLine();
      }
   }
}

Step 2 - As informações do terminal (igual ao serviço) devem ser adicionadas ao arquivo de configuração do aplicativo cliente.

<?xmlversion = "1.0"encoding = "utf-8" ?>
<configuration>
   <system.serviceModel>
      <client>
         <endpoint address 
            ="http://localhost:8090/MyCalculatorServiceProxy/ISimpleCalculator"
            binding = "wsHttpBinding" contract "MyCalculatorServiceProxy.ISimpleCalculator">
            </endpoint>
      </client>
   </system.serviceModel>
</configuration>

Step 3- Antes de executar o aplicativo cliente, você precisa executar o serviço. Abaixo, é mostrado o resultado do aplicativo cliente.

Consumindo serviço WCF hospedado no WAS

Consumir um serviço WCF hospedado no WAS é um processo simples que envolve apenas algumas etapas. As etapas são as seguintes -

  • Adicione a classe de proxy e o arquivo de configuração ao aplicativo cliente.
  • Crie o objeto para o MathServiceClient e chame o método.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespaceWASHostedClient {
   classProgram {
      staticvoid Main(string[] args) {
         MathServiceClient client = newMathServiceClient();
         Console.WriteLine("Sum of two number 5,6");
         Console.WriteLine(client.Add(5, 6));
         Console.ReadLine();
      }
   }
}

A saída aparece conforme mostrado abaixo.

Consumindo serviço WCF hospedado no serviço Windows

O processo passo a passo de como consumir um serviço WCF hospedado no Windows Service é expresso abaixo em detalhes com codificação e instruções.

Uma vez hospedado com sucesso, podemos criar uma classe proxy para o serviço e começar a usar no aplicativo cliente. Aqui, ele é mostrado com o tipo de hospedagem IIS consumindo.

Adicione a referência de ServiceModel.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespaceWindowServiceClient {
   classProgram {
      staticvoid Main(string[] args) {
         //Creating Proxy for the MyService
         MyServiceClient client = newMyServiceClient();
         Console.WriteLine("Client calling the service...");
         Console.WriteLine("Sum of two numbers 5,6");
         Console.WriteLine(client.Add(5, 6));
        
         Console.WriteLine("Subtraction of two numbers 6,5");
         Console.WriteLine(client.Sub(6, 5));
        
         Console.WriteLine("Multiplication of two numbers 6,5");
         Console.WriteLine(client.Mul(6, 5));
        
         Console.WriteLine("Division of two numbers 6,3");
         Console.WriteLine(client.Div(6, 3));
         Console.Read();
      }
   }
}

A saída aparece da seguinte forma -

A associação de serviço WCF é um conjunto de vários elementos em que cada elemento define a maneira como o serviço está se comunicando com o cliente. Um elemento de transporte e um elemento de codificação de mensagem são os dois componentes mais vitais de cada ligação. Neste capítulo, discutiremos várias associações de serviço WCF que são comumente usadas.

Ligação Básica

A vinculação básica é oferecida pela classe BasicHttpBinding. Ele usa o protocolo HTTP para transportar e representar um serviço WCF como um serviço da Web ASP.NET (serviço da Web ASMX), para que clientes antigos que usam os serviços da Web ASMX possam consumir os novos serviços de maneira conveniente.

A vinculação básica é definida como vinculação padrão em um serviço da web WCF habilitado pelo Silverlight e é uma vinculação padrão para comunicações no estilo de serviço da web. Ele não oferece suporte a mensagens confiáveis.

Abaixo está um trecho de código que descreve as configurações padrão para ligação básica.

<basicHttpBinding>
   <binding name = "basicHttpBindingDefaults" allowCookies = "false" 
      bypassProxyOnLocal = "false" hostNameComparisonMode = "StrongWildcard" 
      maxBufferPoolSize = "524288" maxBufferSize = "65536" 
      maxReceivedMessageSize = "65536" messageEncoding = "Text" proxyAddress = "" 
      textEncoding = "utf-8" transferMode = "Buffer" useDefaultWebProxy = "true" 
      closeTimeout = "00:01:00" openTimeout = "00:01:00" receiveTimeout = "00:10:00" 
      sendTimeout = "00:01:00">
   
      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = "4096" 
         maxDepth = "32"
         maxNameTableCharCount = "16384" maxStringContentLength = "8192"/>

      <security mode = "None">
         <transport clientCredentialType = "None" proxyCredentialType = "None" realm = ""/>
         <message algorithmSuite = "Basic256" clientCredentialType = "UserName" />
      </security>       
   </binding>

</basicHttpBinding>

As configurações padrão acima têm suas limitações óbvias, pois o tamanho da mensagem é limitado e não há modo de segurança. No entanto, a personalização da vinculação básica resolve esse problema como o mostrado abaixo.

<basicHttpBinding>
   <binding name = "basicHttpSecure" maxBufferSize = "100000" maxReceivedMessageSize = "100000">
   
      <readerQuotas maxArrayLength = "100000" maxStringContentLength = "100000"/>
      <security mode = "TransportWithMessageCredential" />
     
   </binding>
</basicHttpBinding>

Web Service Binding

A ligação de serviço da Web (WS) é fornecida pela classe WSHttpBinding. É bastante semelhante à ligação básica e usa os mesmos protocolos para transporte, mas oferece várias especificações WS– *, como WS – Reliable Messaging, WS – Transactions, WS – Security e muitos mais. Em suma, WSHttpBinding é igual à soma das especificações basicHttpBinding e WS– *. Abaixo está um trecho de código que descreve as configurações padrão para WS Binding -

<wsHttpBinding>
   <binding name = "wsHttpBindingDefaults" allowCookies = "false" 
      bypassProxyOnLocal = "false" closeTimeout = "00:01:00" 
      hostNameComparisonMode = "StrongWildcard" 
      maxBufferPoolSize = "524288" maxReceivedMessageSize = "65536" 
      messageEncoding = "Text" openTimeout = "00:01:00" 
      receiveTimeout = "00:10:00" proxyAddress = "" sendTimeout = "00:01:00" 
      textEncoding = "utf-8" transactionFlow = "false" 
      useDefaultWebProxy = "true" > 
   
      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = ."4096" 
         maxDepth = "32" maxNameTableCharCount = "16384" 
         maxStringContentLength = "8192"/>

      <reliableSession enabled = "false" ordered = "true" 
         inactivityTimeout = "oo:10:00" /> 

      <security mode = "Message">
         <message algorithmSuite = "Basic256" clientCredentialType = "Windows" 
            esatalishSecurityContext = "true" 
            negotiateServiceCredential = "true" />

         <transport clientCredentialType = "Windows"
            proxyCredentialType = "None" realm = ""/>        	
      </security>
      
   </binding>
</wsHttpBinding>

Ligação IPC

A vinculação IPC usa o pipe nomeado e é oferecida pela classe netNamedPipeBinding. Esta é a encadernação mais rápida e segura entre todas as encadernações disponíveis. Embora a segurança no nível da mensagem não seja suportada aqui, as mensagens são seguras por padrão devido a uma segurança de transporte robusta. A seguir está o trecho de código que descreve as configurações padrão para vinculação IPC -

<netNamedPipeBinding>
   
   <binding name = "netPipeDefaults" closeTimeout = "00:01:00" 
      hostNameComparisonMode = "StrongWildcard" maxBufferPoolSize = "524288" 
      maxBufferSize = "65536" maxConnections = "10" 
      maxReceivedMessageSize = "65536" openTimeout = "00:01:00" 
      receiveTimeout = "00:10:00" sendTimeout = "00:01:00" transactionFlow = "false" 
      transactionProtocol = "OleTransactions" transferMode = "Buffered">  

      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = "4096" 
         maxDepth = "32" maxNameTableCharCount = "16384" 
         maxStringContentLength = "8192"/>
   
      <security mode = "Transport">        	
      </security>
      
   </binding>
</netNamedPipeBinding>

Outros tipos de ligações de serviço

  • TCP Binding- Fornecido pela classe NetTCPBinding, essa ligação faz uso do protocolo TCP para comunicação dentro da mesma rede e faz a codificação da mensagem em formato binário. Esta ligação é considerada a mais confiável em comparação com outras.

  • WS Dual Binding- Este tipo de ligação é mais parecido com WSHttpBinding, com a única exceção de que facilita a comunicação bidirecional, ou seja, as mensagens podem ser enviadas e recebidas por clientes e serviços. Ele é oferecido pela classe WSDualHttpBinding.

  • Web binding - A vinculação da Web é projetada para representar serviços WCF na forma de solicitações HTTP pelo uso de HTTP-GET, HTTP-POST, etc. É oferecida pela classe WebHttpBinding e é comumente usada com redes sociais.

  • MSMQ Binding- É oferecido pela classe NetMsmqBinding e serve para fornecer soluções caso o serviço processe uma mensagem em um momento distinto do enviado pelo cliente. A vinculação do MSMQ usa o MSMQ para transporte e fornece suporte para mensagens desanexadas na fila. MSMQ é uma implementação para enfileiramento de mensagens oferecida pela Microsoft.

  • Federated WS Binding- É uma forma específica de ligação WS e oferece suporte para segurança federada. Ele é oferecido pela classe WSFederationHttpBinding.

  • Peer Network Binding- Oferecido pela classe NetPeerTCPBinding, é usado principalmente em sistemas de compartilhamento de arquivos. Ele usa o protocolo TCP, mas faz uso da rede de pares como transporte. Nessa rede, cada máquina (nó) atua como cliente e servidor para os outros nós. A vinculação de rede de mesmo nível é usada em sistemas de compartilhamento de arquivos como torrent.

  • MSMQ Integration Binding - Oferecido pela classe MsmqIntegrationBinding, ajuda a se comunicar com os sistemas existentes que se comunicam via MSMQ (Microsoft Message Queuing).

Além disso, também é possível criar ligações personalizadas. No entanto, como é possível ajustar as propriedades de configuração de cada associação do WCF, raramente surge a necessidade de criar associações personalizadas.

O conjunto de técnicas empregadas pelo WCF para vincular um conjunto de mensagens (solicitações do cliente) a instâncias de serviço é conhecido como Gerenciamento de Instâncias. O WCF oferece suporte a três tipos de ativação de instância e eles são discutidos neste capítulo.

Serviço por chamada

O serviço por chamada é o modo de ativação de instância padrão do WCF. Quando um serviço WCF é configurado para um serviço por chamada, um objeto CLR é criado para o intervalo de tempo em que uma chamada ou solicitação do cliente está em andamento. CLR significa Common Language Runtime e inclui instâncias de serviço no WCF.

No serviço por chamada, cada solicitação do cliente atinge uma nova instância de serviço dedicada e seu consumo de memória é menor em comparação com outros tipos de ativação de instância.

A propriedade InstanceContextMode deve ser definida como InstanceContextMode.PerCall, a fim de indicar um serviço WCF para atuar como um serviço por chamada. A propriedade InstanceContextMode pertence ao atributo ServiceBehavior. Portanto, um serviço por chamada pode ser configurado da seguinte forma -

[ServiceContract]
interface IMyContract
{...}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}

Um serviço é expresso aqui como IMyContract. A figura a seguir mostra o processo de ativação da instância de serviço por chamada.

Implementando um serviço por chamada

[DataContract]
class Param {....}

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod(Param objectIdentifier);
}
class MyPerCallService : IMyContract, IDisposable {
   public void MyMethod(Param objectIdentifier) {
      GetState(objectIdentifier); 
      DoWork();
      SaveState(objectIdentifier);
   }
   
   void GetState(Param objectIdentifier) {....}
   void DoWork() {....}
   void SaveState(Param objectIdentifier) {....}
   public void Dispose() {....}
}

Aqui, Param é o parâmetro de pseudo tipo inventado para o exemplo acima.

Serviço por sessão

Neste modo de ativação do WCF, uma sessão privada ou podemos dizer que uma sessão confidencial é mantida entre as duas entidades, ou seja, o cliente e uma instância de serviço particular. Também conhecido como serviço de sessão privada, o serviço por sessão oferece uma nova instância de serviço que permanece dedicada a cada solicitação do cliente e autônoma de todas as outras instâncias pertencentes a esse serviço ciente de sessão.

Para iniciar um serviço por sessão, a propriedade InstanceContextMode deve ser definida como PerSession. Aqui, a instância de serviço permanece na memória durante toda a duração da sessão.

O modo de ativação sofre de escalabilidade, pois o serviço configurado é incapaz de oferecer suporte a quaisquer clientes pendentes adicionais além de alguns (ou talvez até algumas centenas) devido ao custo envolvido em cada uma dessas instâncias de serviço dedicado.

Um serviço por sessão pode ser configurado como -

[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{...}

O processo de serviço por sessão pode ser descrito conforme mostrado na figura a seguir -

O código a seguir mostra um contrato e serviço configurado para o uso de uma sessão privada. A saída indica que o cliente realmente obteve uma instância de serviço dedicada.

Código de Serviço

[ServiceContract(Session = true)]
interface IMyContract {
   [OperationContract]
   void MyMethod();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable {
   int m_Counter = 0; MyService() {Console.WriteLine("MyService.MyService()"); }
   
   public void MyMethod() {
      m_Counter++;
      Console.WriteLine("Counter = " + m_Counter);
   }
   public void Dispose() { 
      Console.WriteLine("MyService.Dispose()"); 
   }
}

Código do cliente

MyContractProxy proxy = new MyContractProxy(); proxy.MyMethod(); proxy.MyMethod(); 
proxy.Close();

Resultado

MyService.MyService() Counter = 1 Counter = 2 MyService.Dispose()

Serviço Singleton

Nesse modo de ativação do WCF, todas as solicitações de clientes independentes umas das outras são conectadas à mesma instância única bem conhecida, independentemente de sua conexão com os terminais de serviço. O serviço singleton é descartado apenas quando o host é encerrado.

Este serviço é criado apenas uma vez quando o host é criado. Caso o host não tenha nenhuma instância singleton, o serviço retorna como NULL. O modo de ativação é melhor quando a quantidade de trabalho em cada chamada de método é pequena e não há operações pendentes em segundo plano.

A propriedade InstanceContextMode é necessária para definir como InstanceContextMode.Single para iniciar este serviço Singleton.

Portanto, um serviço Singleton pode ser configurado como -

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}

O processo de serviço Singleton é mostrado na figura a seguir -

O código a seguir é usado para inicializar e hospedar uma instância singleton.

Código de Serviço

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod( );
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : IMyContract {
   int m_Counter = 0;
   
   public int Counter {
      get {
         return m_Counter;
      }
      set {
         m_Counter = value;
      }
   }
   public void MyMethod( ) {
      m_Counter++;
      Trace.WriteLine("Counter = " + Counter);
   }
}

Código de host

MySingleton singleton = new MySingleton( );
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open( );

//Do some blocking calls then
host.Close( );

Código do cliente

MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( );
proxy.Close( );

Resultado

Counter = 43

Uma transação no WCF é um conjunto de operações que seguem algumas propriedades, conhecidas coletivamente como ACID. Aqui, se uma única operação falhar, todo o sistema falhará automaticamente. Quando um pedido é feito online, uma transação ocorre. O exemplo a seguir pode ser útil para entender o processo de transação em termos mais simples.

Exemplo

Suponha que você tenha pedido uma televisão LCD em uma loja online e vá pagar o valor com cartão de crédito. Quando você insere as informações necessárias para fazer o pedido, duas operações ocorrem simultaneamente.

Um, o valor especificado é debitado de sua conta bancária e, segundo, a conta do fornecedor é creditada com o mesmo valor. Ambas as operações devem ser executadas com sucesso para que a transação seja bem-sucedida.

Propriedades de transação WCF

As quatro propriedades seguidas por uma transação WCF são as seguintes -

  • Atomic - Todas as operações devem atuar como uma única operação indivisível na conclusão de uma transação.

  • Consistency - Qualquer que seja a operação definida, o sistema está sempre em estado de consistência, ou seja, o resultado da transação é sempre conforme a expectativa.

  • Isolation - O estado intermediário do sistema não é visível para nenhuma entidade do mundo exterior até que a transação seja concluída.

  • Durability - O estado confirmado é mantido independentemente de qualquer tipo de falha (hardware, queda de energia, etc.)

Ao configurar uma transação WCF, existem alguns fatores que exigem consideração. Estes são os comportamentos de ligação e operação.

Binding- As ligações que oferecem suporte à transação no WCF são apenas algumas e é vital fazer uma escolha entre apenas essas ligações, que permanecem desabilitadas por padrão e devem ser habilitadas para obter o suporte necessário para a transação. Essas ligações são as seguintes -

  • NetTcpBinding
  • NetNamedPipeBinding
  • WSHttpBinding
  • WSDualHttpBinding
  • WSFederationHttpBinding

Operation behavior- Enquanto uma ligação facilita o caminho para a propagação da transação, uma operação cuida do processamento da transação, bem como da configuração da operação. O comportamento da operação usa principalmente dois atributos: TransactionFlow e TransactionScopeRequired. Aqui, deve-se observar que TransactionFlow tem principalmente três valores e são: Permitido, Obrigatório e Não Permitido.

O código a seguir mostra se a alteração da configuração de ligação e contrato de operação facilita ou não a propagação do cliente.

<bindings> 
   <wsHttpBinding> 
      <binding name = "MandatoryTransBinding" transactionFlow = "true"> 
         <reliableSession enabled ="true"/>
      </binding>
   </wsHttpBinding> 
</bindings>

Protocolo de Transação

O WCF usa três tipos de protocolos para transações -

  • Lightweight
  • Transação Ole
  • Transação WS-Atomic (WS-AT)

De todos os três, o WS-AT é um protocolo interoperável e permite o fluxo de transações distribuídas entre firewalls. No entanto, este protocolo não deve ser usado quando a transação for estritamente baseada em tecnologia Microsoft.

Fases da transação WCF

Existem duas fases em uma transação WCF, conforme mostrado na figura a seguir.

  • Prepare Phase - Nesta fase, o gerenciador de transações verifica se todas as entidades estão prontas para confirmar a transação ou não.

  • Commit Phase - Nesta fase, o empenho das entidades começa na realidade.

A figura a seguir ilustra as funções de ambas as fases de uma transação WCF.

Habilitando uma transação WCF

Para habilitar uma transação WCF com êxito, é necessário seguir uma série de seis etapas de maneira sequencial. As etapas necessárias são discutidas abaixo.

Step 1 − Creation of two WCF Services

A etapa mais importante a esse respeito é construir dois projetos de serviço no WCF para participar de uma única transação. As transações de banco de dados serão executadas em ambos os serviços e será entendido como eles são unificados por uma transação WCF. Um aplicativo da web de WCFTransactions também foi criado para consumir os dois serviços criados em um único escopo de transação.

Step 2 − Method creation and its attribution with TransactionFlow attribute

Aqui, um método UpdateData será criado para ambos os serviços WCF para inserir no banco de dados com o atributo OperationContract. Para realizar essa tarefa, uma classe de interface é criada primeiro com a ajuda do atributo ServiceContract. Para habilitar a transação no método recém-criado, ela é atribuída com TransactionFlow e as transações são permitidas usando seu valor Permitido.

[ServiceContract]
public interface IService1 {
   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   void UpdateData();
}

Step 3− Implementation of WCF service with TransactionScopeRequired attribute

Isso é feito usando o código mostrado abaixo -

[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateData() {
   try {
      SqlConnection objConnection = new SqlConnection(strConnection);
      objConnection.Open();
      
      using(SqlTransaction transaction = Program.dbConnection.BeginTransaction()) {
     	   Boolean doRollback = false;
     	   using(SqlCommand cmd = new SqlCommand(
            "insert into Customer (Customer name, Customer code) values ('sss', 'sss')"objConnection))
         
     	   try {
            cmd.ExecuteNonQuery();
     	   } catch(SqlException) {
            doRollback = true;
            break;
     	   }
      }
      
      if(doRollback)
         transaction.Rollback();
      else
         transaction.Commit();  
   }
   finally {
      objConection.Close();
   }
}

Step 4 − Enabling Transaction Flow by WCF Service Config File

Sua codificação é feita da seguinte forma -

<bindings>
   <wsHttpBinding>
      <binding name = "TransactionalBind" transactionFlow = "true"/>
   </wsHttpBinding>
</bindings>

É vital anexar a ligação permissível da transação com o ponto de extremidade para expor o serviço WCF.

<endpoint address = "" binding = "wsHttpBinding" bindingConfiguration = "TransactionalBind" contract = "WcfService1.IService1">

Step 5 − Calling both the services in a single transaction

Aqui, os dois serviços acima são chamados em uma transação e, para esse propósito, o objeto TransactionScope é usado para agrupar ambos os serviços. O método Complete do objeto acima é chamado para confirmar uma transação WCF. Para reverter, o método Dispose deve ser chamado.

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      // Call your webservice transactions here
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

A pequena parte do código completo em que as transações WCF foram agrupadas em um escopo é ilustrada abaixo -

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      ServiceReference1.Service1Client obj = newServiceReference1.Service1Client();
      obj.UpdateData();
      ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
      obj1.UpdateData();
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

Step 6 − Testing WCF transaction

O teste é feito na 6ª e última etapa e, após chamar o primeiro serviço WCF, uma exceção é forçada.

O WCF RIA Service é uma estrutura de nível superior e um novo componente de estruturas como .NET 4 e Silverlight 4 que facilita o procedimento de construção de um aplicativo de negócios complexo no Silverlight, oferecendo validação do lado do cliente. RIA significa Rich Internet Applications.

Deve-se destacar aqui que o Silverlight é um framework oferecido pela Microsoft, ideal para aplicações ricas de internet e está disponível para uso como plug-in de navegador, assim como o Adobe Flash.

O serviço WCF RIA é baseado principalmente na versão padrão do serviço WCF. A figura a seguir ilustra uma parte da arquitetura WCF, onde os serviços WCF RIA têm seu foco em geral.

Criar um serviço WCF RIA é a próxima etapa para ter uma melhor compreensão do conceito. O procedimento passo a passo é fornecido abaixo.

Step 1 - Crie um novo projeto da web com o nome SLWCFRiaServices.Web usando Silverlight 5 e, em seguida, adicione um novo item selecionando ADO.NET Entity Data Model para o mesmo.

Step 2 - Agora escolha o conteúdo do modelo no Assistente de modelo de dados de entidade, gerando o modelo no banco de dados.

Step 3 - No mesmo assistente, escolha sua conexão de dados e objetos de banco de dados.

Step 4 - Construa a solução para que, no futuro, reconhecer o modelo de dados não seja um problema para o serviço de domínio que você vai criar.

Step 5 - Agora crie um serviço de domínio no projeto da web adicionando um novo item e certifique-se de habilitar o acesso do cliente.

Step 6 - Já na próxima etapa, algumas classes serão geradas e é essencial reconstruí-las.

Step 7 - Nesta etapa, DataDomainContext é exibido pelo Painel de Fontes de Dados.

Step 8 - Nesta etapa, o artigo abaixo do DataDomainContext deve ser selecionado e personalizado.

Step 9- Anexar o Controle DataGrid com a Fonte de Dados é a etapa comprometida aqui, junto com a seleção de temas. Aqui, o tema BureauBlue foi selecionado.

Step 10- A última e última etapa consiste em ir para a tela de design e adicionar entidade na área de layout da MainPage simplesmente arrastando e soltando. Também é vital garantir que AutoGenerateColumns = "True" e executá-lo para visualizar a saída.

Pré-requisitos

Existem alguns pré-requisitos para experimentar todo o potencial dos serviços WCF RIA -

  • Visual Studio 2010 / Visual Studio 2012
  • Silverlight Developer Runtime
  • Versão mais recente do RIA Services Toolkit
  • SDK (kit de desenvolvimento de software)

Serviço de domínio WCF RIA

Um serviço de domínio é composto por um conjunto de operações de dados relacionadas ao negócio. Nada mais é do que um serviço WCF que expõe a lógica de negócios de qualquer aplicativo WCF RIA Service.

Um WCF RIA Domain Service tem a classe de hospedagem DomainServiceHost internamente, que por sua vez usa a classe WCF ServiceHost para hospedar o aplicativo. Para tornar o serviço de domínio acessível para o projeto do cliente, ele deve ter o atributo EnableClientAccessAttribute. O atributo é aplicado automaticamente sempre que uma nova classe de serviço de domínio é adicionada.

A figura a seguir mostra a arquitetura de um WCF RIA Domain Service -

Serviços WCF RIA - Consultando dados

A figura a seguir mostra como uma consulta é criada no lado do cliente e executada no lado do servidor para retornar resultados consultáveis. DAL significa Camada de Acesso a Dados.

Serviços WCF RIA - Atualizando Dados

A figura a seguir mostra como os dados são atualizados executando a operação CUD (Create Update Delete) no lado do servidor. Deve-se observar aqui que o serviço WCF RIA é sempre sem estado no lado do servidor.

Um serviço WCF se orgulha de um sistema de segurança robusto com dois modos ou níveis de segurança para que apenas um cliente pretendido possa acessar os serviços. As ameaças de segurança comuns em uma transação distribuída são moderadas em grande parte pelo WCF.

Principais recursos de segurança

O serviço WCF tem quatro recursos principais de segurança, conforme ilustrado na figura abaixo.

  • Authentication - Aqui, a autenticação não se limita a identificar o remetente da mensagem, mas é mútua, ou seja, a autenticação do receptor da mensagem é necessária para descartar a possibilidade de qualquer tipo de ataque de intermediário.

  • Authorization- Esta é a próxima etapa realizada por um serviço WCF para garantir a segurança e é aqui determinado se o serviço deve autorizar o chamador a prosseguir ou não. Embora a autorização não dependa da autenticação, normalmente segue a autenticação.

  • Confidentiality- A troca de informações entre um chamador e um serviço é mantida em sigilo para restringir sua interpretação por terceiros para os quais a mensagem não se destina. Para tornar isso possível, a criptografia é usada junto com uma ampla variedade de outros mecanismos.

  • Integrity - O último conceito-chave é manter a integridade, ou seja, oferecer a garantia de que a mensagem não foi adulterada por ninguém em sua jornada do remetente ao destinatário.

Modo de segurança de transferência

O WCF oferece os seguintes modos de segurança de transferência para garantir uma comunicação segura entre um cliente e um servidor. Os diversos modos de segurança de transferência são mencionados abaixo.

  • None- Este modo não garante nenhum tipo de segurança da mensagem e o serviço não obtém nenhuma credencial sobre o cliente. Este modo é altamente arriscado, pois pode permitir a adulteração de mensagens e, portanto, não é recomendado.

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "None"/>
   </binding>
</wsHttpBinding>
  • Transport- Este modo é a maneira mais fácil de obter uma transferência segura de mensagem por meio do uso de protocolos de comunicação como TCP, IPC, Https e MSMQ. Este modo é mais eficaz quando a transferência é ponto a ponto e é usada principalmente em um ambiente controlado, ou seja, aplicativos de intranet.

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Transport"/>
   </binding>
</wsHttpBinding>
  • Message- O modo de segurança permite autenticação mútua e oferece privacidade em grande parte, pois as mensagens são criptografadas e podem ser transportadas através de http, que não é considerado um protocolo seguro. Aqui, a segurança é fornecida de ponta a ponta, sem considerar quantos intermediários estão envolvidos em uma transferência de mensagem e se há um transporte seguro ou não. O modo é usado normalmente por aplicativos da Internet.

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Message"/>
   </binding>
</wsHttpBinding>
  • Mixed - Este modo de segurança não é usado com frequência e a autenticação do cliente é oferecida apenas no nível do cliente.

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "TransportWithMessageCredential"/>
   </binding>
</wsHttpBinding>
  • Both- Este modo de segurança é composto por segurança de transporte e segurança de mensagem para oferecer uma cobertura de segurança robusta, mas muitas vezes resulta na sobrecarga do desempenho geral. Este é compatível apenas com o MSMQ.

<netMsmqBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Both"/>
   </binding>
</netMsmqBinding>

Todas as ligações WCF, exceto BasicHttpBinding, têm alguma extensão de segurança de transferência por padrão.

Nível de segurança da mensagem

A segurança de nível de mensagem não depende de protocolos WCF. Ele é empregado com os próprios dados da mensagem, criptografando-os usando um algoritmo padrão. Várias credenciais de cliente estão disponíveis para diferentes ligações para o nível de segurança da mensagem e são discutidas a seguir.

Client credentials for message level security in WCF

None- Aqui, a criptografia é usada para proteger a mensagem, enquanto nenhuma autenticação de cliente é realizada, o que significa que o serviço pode ser acessado por um cliente anônimo. Exceto para BasicHttpBinding, todas as ligações WCF oferecem suporte a essa credencial de cliente. No entanto, deve-se observar que para NetNamedPipeBinding, essa credencial de cliente não está disponível.

  • Windows- Aqui, a criptografia da mensagem e a autenticação do cliente ocorrem para um usuário conectado em tempo real. Nesse caso também, ao contrário de todas as outras associações do WCF, NetNamedPipeBinding não está disponível e BasicHttpBinding não oferece seu suporte.

  • UserName- Aqui, as mensagens são criptografadas, bem como protegidas, oferecendo um nome de usuário, e os clientes são autenticados quando precisam oferecer uma senha. BasicHttpBinding, assim como as duas credenciais de cliente acima, não oferece suporte a UserName e não está disponível para NetNamedPipeBinding.

  • Certificate- Junto com a criptografia de mensagem, o cliente e o serviço obtêm uma autenticação com certificado. Essa credencial de cliente está disponível e é compatível com todas as ligações WCF, exceto NetNamedPipeBinding.

  • IssuedToken- Tokens emitidos por uma autoridade como Cardspace são usados ​​para autenticar as mensagens. A criptografia de mensagens também é realizada aqui.

O código a seguir mostra como as credenciais do cliente são configuradas no nível / modo de segurança da mensagem WCF.

<netTcpBinding>
   <binding name = "WCFMessageSecurityExample">
      <security mode = "Message">
         <message clientCredentialType = "None"/>
      </security>   
   </binding>
</netTcpBinding>

<netMsmqBinding>...</netMsmqBinding>
</bindings>
<behaviors>...</behaviors>

Aqui, deve-se observar que o modo de segurança de transporte tem uma vantagem sobre o nível de segurança da mensagem, pois o primeiro é mais rápido. Não requer nenhuma codificação adicional e oferece suporte de interoperabilidade e, portanto, não reduz o desempenho geral.

No entanto, do ponto de vista da segurança, o modo de segurança da mensagem é mais robusto e independente de protocolos e oferece segurança ponta a ponta.

Um desenvolvedor de serviço WCF pode encontrar alguns erros imprevistos que requerem relatórios ao cliente de maneira adequada. Esses erros, conhecidos comoexceptions, normalmente são manipulados usando blocos try / catch, mas, novamente, isso é muito específico da tecnologia.

Uma vez que a área de preocupação do cliente não é sobre como ocorreu um erro ou os fatores que contribuíram para um erro, o contrato de falha SOAP é usado para comunicar a mensagem de erro do serviço ao cliente no WCF.

Um contrato de falha permite que o cliente tenha uma visão documentada dos erros ocorridos em um serviço. O exemplo a seguir oferece uma melhor compreensão.

Step 1 - Um serviço de calculadora fácil é criado com a operação de divisão que irá gerar exceções gerais.

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

namespace Calculator {
   // NOTE: You can use the "Rename" command on the "Refactor" menu to change 
   // the interface name "IService1" in both code and config file together.
   
   [ServiceContract]
   
   public interface IService1 {
      [OperationContract]
      int divide(int num1, int num2);
      // TODO: Add your service operations here
   }
}

A codificação do arquivo de classe é mostrada abaixo -

Agora, quando tentamos dividir o número 10 por zero, o serviço de calculadora lançará uma exceção.

A exceção pode ser tratada pelo bloco try / catch.

Agora, quando tentamos dividir qualquer número inteiro por 0, ele retornará o valor 10 porque o tratamos no bloco catch.

Step 2 - FaultException é usado nesta etapa para comunicar as informações de exceção ao cliente do serviço.

public int Divide(int num1, int num2) { 
   //Do something 
   throw new FaultException("Error while dividing number"); 
}

Step 3- Também é possível criar um tipo personalizado para enviar a mensagem de erro usando FaultContract. As etapas essenciais para criar um tipo personalizado são mencionadas abaixo -

Um tipo é definido pelo uso de contrato de dados e os campos destinados a serem retornados são especificados.

A operação de serviço é decorada pelo atributo FaultContract. O nome do tipo também é especificado.

Uma instância de serviço é criada para levantar exceções e propriedades de exceção personalizadas são atribuídas.