Como: Migrar serviços Web de ASP.NET habilitados para AJAX para WCF
Este tópico descreve os procedimentos para migrar um serviço AJAX ASP.NET básico para um serviço Windows Communication Foundation (WCF) habilitado para AJAX equivalente. 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 ASP.NET AJAX existente para um serviço WCF AJAX 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 dos 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 que resulta 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 o tópico Como usar a configuração para adicionar um ponto de extremidade AJAX ASP.NET.
Para criar e testar o aplicativo de serviço Web ASP.NET
Abra o Visual Studio 2012.
No menu Arquivo, selecione Novo, Projeto, Web e ASP.NET Aplicativo de Serviço Web.
Nomeie o projeto
ASPHello
e clique em OK.Descomente a linha no arquivo de Service1.asmx.cs que contém
System.Web.Script.Services.ScriptService]
para habilitar o AJAX para este serviço.No menu Build, selecione Build Solution.
No menu Depurar, selecione Iniciar Sem Depuração.
Na página da Web gerada, selecione a
HelloWorld
operação.Clique no botão Invocar na página de
HelloWorld
teste. Você deve receber a seguinte resposta XML.<?xml version="1.0" encoding="utf-8" ?> <string xmlns="http://tempuri.org/">Hello World</string>
Essa resposta confirma que agora você tem um serviço ASP.NET AJAX em funcionamento e, em particular, que o serviço agora expôs um ponto de extremidade em Service1.asmx/HelloWorld que responde a solicitações HTTP POST e retorna XML.
Agora você está pronto para converter este serviço para usar um serviço WCF AJAX.
Para criar um aplicativo de serviço WCF AJAX equivalente
Clique com o botão direito do mouse no projeto ASPHello e selecione Adicionar, Novo Item e Serviço WCF habilitado para AJAX.
Nomeie o serviço
WCFHello
e clique em Adicionar.Abra o arquivo WCFHello.svc.cs.
De Service1.asmx.cs, copie a seguinte implementação da
HelloWorld
operação.public string HelloWorld() { return "Hello World"; }
Cole a implementação copiada da
HelloWorld
operação no arquivo WCFHello.svc.cs em vez do código a seguir.public void DoWork() { // Add your operation implementation here return; }
Especifique o
Namespace
atributo para ServiceContractAttribute comoWCFHello
.[ServiceContract(Namespace="WCFHello")] [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)] public class WCFHello { … }
Adicione o WebInvokeAttribute à
HelloWorld
operação e defina a ResponseFormat propriedade para retornar Xml. Observe que, se não estiver definido, o tipo de retorno padrão é Json.[OperationContract] [WebInvoke(ResponseFormat=WebMessageFormat.Xml)] public string HelloWorld() { return "Hello World"; }
No menu Build, selecione Build Solution.
Abra o arquivo WCFHello.svc e, no menu Depurar , selecione Iniciar sem Depuração.
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 a partir do navegador, mas o ponto de extremidade retorna XML após XML.<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
Os
WCFHello.svc/HelloWorld
pontos finais e sãoService1.aspx/HelloWorld
agora funcionalmente equivalentes.
Exemplo
O código que resulta 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].
}
}
O XmlDocument tipo não é suportado DataContractJsonSerializer pelo porque não é serializável pelo XmlSerializer. Você pode usar um XDocument tipo ou serializar o DocumentElement em vez disso.
Se os serviços Web ASMX estiverem sendo atualizados e migrados lado a lado para serviços WCF, evite mapear dois tipos para o mesmo nome no cliente. Isso causa uma exceção nos 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 ASMX Web Service causará exceção porque ConvertValue(Object, Type, String) 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 porque DataContractJsonSerializer a definição de estilo do Serviço Web da ordem no proxy terá precedência.
Existem diferenças significativas no comportamento entre o DataContractJsonSerializer AJAX JavaScriptSerializere o ASP.NET. Por exemplo, o DataContractJsonSerializer representa um dicionário como uma matriz de pares chave/valor, enquanto o ASP.NET AJAX JavaScriptSerializer representa um dicionário como objetos JSON reais. Assim, o seguinte é o dicionário representado em ASP.NET AJAX.
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("one", 1);
d.Add("two", 2);
Este dicionário é representado em objetos JSON, conforme mostrado na lista a seguir:
[{"Key":"one","Value":1},{"Key":"two","Value":2}] pelo DataContractJsonSerializer
{"one":1,"two":2} pelo ASP.NET AJAX JavaScriptSerializer
O DataContractJsonSerializer é mais poderoso no sentido de que ele pode lidar com dicionários onde o tipo de chave não é string, enquanto o JavaScriptSerializer não pode. Mas este último é mais amigável ao JSON.
As diferenças significativas entre esses serializadores são resumidas na tabela a seguir.
Categoria de diferenças | DataContractJsonSerializer | ASP.NET AJAX JavaScriptSerializer |
---|---|---|
Desserialização do buffer vazio (novo byte[0]) em Object (ou Uri, ou algumas outras classes). | SerializationException | nulo |
Serialização de Value | {} (ou {"__type":"#System"}) | Nulo |
Serialização dos membros privados dos tipos [Serializable]. | serializado | não serializado |
Serialização das propriedades públicas dos ISerializable tipos. | não serializado | serializado |
"Extensões" do JSON | Adere à especificação JSON, que requer aspas em nomes de membros de objeto ({"a":"hello"}). | Suporta os nomes dos membros do objeto sem aspas ({a:"hello"}). |
DateTime Tempo Universal Coordenado (UTC) | Não suporta o formato "\/Date(123456789U)\/" ou "\/Date\(\d+(U|( \+\-[\d{4}])?\)\\/)". | Suporta o formato "\/Date(123456789U)\/" e "\/Date\(\d+(U|( \+\-[\d{4}])?\)\\/)" como valores DateTime. |
Representação de dicionários | Uma matriz de KeyValuePair<K,V>, manipula tipos de chave que não são strings. | Como objetos JSON reais - mas apenas manipula tipos de chave que são cadeias de caracteres. |
Personagens escapados | Sempre com uma barra de escape (/); nunca permite caracteres JSON inválidos sem escape, como "\n". | Com uma barra de escape (/) para valores DateTime. |