Compartilhar via


Como: migrar serviços Web habilitados para AJAX ASP.NET para o WCF

Este tópico descreve os procedimentos para migrar um serviço básico AJAX ASP.NET para um serviço equivalente WCF (Windows Communication Foundation) habilitado para AJAX. Ele mostra como criar uma versão WCF funcionalmente equivalente de um serviço AJAX ASP.NET. Os dois serviços podem ser usados lado a lado ou o serviço WCF pode ser usado para substituir o serviço AJAX ASP.NET.

A migração de um serviço AJAX ASP.NET existente para um serviço AJAX do WCF oferece os seguintes benefícios:

  • Você pode expor seu serviço AJAX como um serviço SOAP com configuração extra mínima.

  • Você pode se beneficiar de recursos do WCF, como rastreamento e assim por diante.

Os procedimentos a seguir pressupõem que você esteja usando o Visual Studio 2012.

O código resultante dos procedimentos descritos neste tópico é fornecido no exemplo a seguir aos procedimentos.

Para obter mais informações sobre como expor um serviço WCF por meio de um ponto de extremidade habilitado para AJAX, consulte Como usar a configuração para adicionar um tópico do ponto de extremidade AJAX ASP.NET.

Para criar e testar um aplicativo de serviço Web do ASP.NET

  1. Abra o Visual Studio 2012.

  2. No menu Arquivo, selecione Novo e, em seguida, Projeto, Web e, a seguir, selecione Aplicativo de Serviço Web do ASP.NET.

  3. Dê um nome para o projeto ASPHello e clique em OK.

  4. Remova a marca de comentário da linha no arquivo Service1.asmx.cs que contém System.Web.Script.Services.ScriptService] para habilitar o AJAX para esse serviço.

  5. No menu Compilar, selecione Compilar Solução.

  6. No menu Depurar, selecione Iniciar sem depurar.

  7. Na página da Web gerada, selecione a operação HelloWorld.

  8. Clique no botão Invocar na página de teste HelloWorld. Você deve receber a seguinte resposta XML.

    <?xml version="1.0" encoding="utf-8" ?>
    <string xmlns="http://tempuri.org/">Hello World</string>
    
  9. Essa resposta confirma que agora você tem um serviço AJAX ASP.NET funcional e, em particular, que o serviço já expôs um ponto de extremidade no Service1.asmx/HelloWorld que responde a solicitações HTTP POST e retorna XML.

    Agora você está pronto para converter esse serviço para usar um serviço AJAX do WCF.

Para criar um aplicativo de serviço equivalente do AJAX WCF

  1. Clique com o botão direito do mouse no projeto ASPHello e selecione Adicionar, depois Novo Item e, em seguida, Serviço WCF habilitado para AJAX.

  2. Dê um nome para o serviço WCFHello e clique em Adicionar.

  3. Abra o arquivo WCFHello.svc.cs.

  4. Em Service1.asmx.cs, copie a seguinte implementação da operação HelloWorld.

    public string HelloWorld()
    {
        return "Hello World";
    }
    
  5. Cole a implementação copiada da operação HelloWorld no arquivo WCFHello.svc.cs no lugar do código a seguir.

    public void DoWork()
    {
          // Add your operation implementation here
          return;
    }
    
  6. Especifique o atributo Namespace para ServiceContractAttribute como WCFHello.

    [ServiceContract(Namespace="WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class WCFHello
    { … }
    
  7. Adicione WebInvokeAttribute à operação HelloWorld e defina a propriedade ResponseFormat a ser retornada a Xml. Observe que, se não estiver definido, o tipo de retorno padrão será Json.

    [OperationContract]
    [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
    public string HelloWorld()
    {
        return "Hello World";
    }
    
  8. No menu Compilar, selecione Compilar Solução.

  9. Abra o arquivo WCFHello.svc e, no menu Depurar, selecione Iniciar Sem Depuração.

  10. O serviço agora expõe um ponto de extremidade em WCFHello.svc/HelloWorld, que responde a solicitações HTTP POST. As solicitações HTTP POST não podem ser testadas no navegador, mas o ponto de extremidade retorna XML após XML.

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
    
  11. Os pontos de extremidade WCFHello.svc/HelloWorld e Service1.aspx/HelloWorld agora são funcionalmente equivalentes.

Exemplo

O código resultante dos procedimentos descritos neste tópico é fornecido no exemplo a seguir.

//This is the ASP.NET code in the Service1.asmx.cs file.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Web.Script.Services;

namespace ASPHello
{
    /// <summary>
    /// Summary description for Service1.
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

//This is the WCF code in the WCFHello.svc.cs file.
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace ASPHello
{
    [ServiceContract(Namespace = "WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class WCFHello
    {
        // Add [WebInvoke] attribute to use HTTP GET.
        [OperationContract]
        [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
        public string HelloWorld()
        {
            return "Hello World";
        }

        // Add more operations here and mark them with [OperationContract].
    }
}

Não há suporte para o tipo XmlDocument por DataContractJsonSerializer porque ele não é serializável pelo XmlSerializer. Ao invés disso, você pode usar um tipo XDocument ou serializar o DocumentElement.

Se os serviços Web ASMX estiverem sendo atualizados e migrados lado a lado para os serviços do WCF, evite mapear dois tipos para o mesmo nome no cliente. Isso causará uma exceção em serializadores se o mesmo tipo for usado em um WebMethodAttribute e um ServiceContractAttribute:

  • Se o serviço WCF for adicionado primeiro, invocar o método no Serviço Web ASMX causará exceção em ConvertValue(Object, Type, String) porque a definição de estilo WCF da ordem no proxy terá precedência.

  • Se o Serviço Web ASMX for adicionado primeiro, invocar o método no serviço WCF causará exceção em DataContractJsonSerializer porque a definição de estilo do Serviço Web da ordem no proxy terá precedência.

Há diferenças significativas no comportamento entre o DataContractJsonSerializer e o AJAX ASP.NET JavaScriptSerializer. Por exemplo, DataContractJsonSerializer representa um dicionário como uma matriz de pares chave/valor, enquanto o AJAX ASP.NET JavaScriptSerializer representa um dicionário como objetos JSON reais. Portanto, o dicionário a seguir é representado em AJAX ASP.NET.

Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("one", 1);
d.Add("two", 2);

Esse dicionário é representado em objetos JSON, conforme mostrado na lista a seguir:

O DataContractJsonSerializer é mais poderoso no sentido de que ele pode lidar com dicionários em que o tipo de chave não é cadeia de caracteres, enquanto o JavaScriptSerializer não pode. Mas o último é mais amigável para JSON.

As diferenças significativas entre esses serializadores são resumidas na tabela a seguir.

Categoria das diferenças DataContractJsonSerializer JavaScriptSerializer AJAX ASP.NET
Desserializando o buffer vazio (novo byte[0]) em Object (ou Uri, ou em algumas outras classes). SerializationException nulo
Serialização de Value {} (ou {"__type":"#System"}) Nulo
Serialização dos membros privados de tipos [serializáveis]. serializado não serializado
Serialização das propriedades públicas de ISerializable tipos. não serializado serializado
"Extensões" do JSON Adere à especificação JSON, que requer aspas em nomes de membro do objeto ({"a":"hello"}). Dá suporte aos nomes dos membros do objeto sem aspas ({a:"hello"}).
DateTime Tempo Universal Coordenado (UTC) Não dá suporte ao formato "\/Date(123456789U)\/" ou "\/Date\(\d+(U|(\+\-[\d{4}]))?\)\\/)". Dá suporte ao formato "\/Date(123456789U)\/" e "\/Date\(\d+(U|(\+\-[\d{4}]))?\)\\/)" como valores DataHora.
Representação de dicionários Uma matriz de KeyValuePair<K,V> manipula tipos de chave que não são cadeias de caracteres. Como objetos JSON reais - mas manipula apenas os tipos de chave que são cadeias de caracteres.
Caracteres de escape Sempre com uma barra de escape para a frente (/); nunca permite caracteres JSON inválidos não escapados, como "\n". Com uma barra de escape para a frente (/) para valores DataHora.

Confira também