Cómo migrar servicios web de ASP.NET con AJAX habilitado a WCF

En este tema se describen los procedimientos para migrar un servicio de AJAX de ASP.NET básico a un servicio Windows Communication Foundation (WCF) de AJAX habilitado equivalente. Muestra cómo crear una funcionalidad de la versión de WCF equivalente de un servicio AJAX de ASP.NET. Los dos servicios se pueden usar en paralelo o el servicio WCF se puede usar para reemplazar el servicio de AJAX de ASP.NET.

Migrar un servicio de AJAX de ASP.NET existente a un servicio de AJAX de WCF le proporciona las siguientes ventajas:

  • Puede exponer su servicio de AJAX como un servicio SOAP con una configuración adicional mínima.
  • Puede aprovecharse de las características de WCF como el seguimiento, etc...

En los procedimientos siguientes se asume que está usando Visual Studio 2008.

El código resultado del procedimiento descrito en este tema se proporciona en el ejemplo que sigue a los procedimientos.

Para obtener más información acerca de que expone un servicio de WCF a través de un extremo con AJAX habilitado, consulte el tema Uso de la configuración para agregar un extremo AJAX de ASP.NET.

Crear y probar la aplicación de servicio web ASP.NET

  1. Abra Visual Studio 2008.

  2. En el menú Archivo, seleccione Nuevo, Proyecto, Web, y, a continuación, seleccione Aplicación de servicio web ASP.NET.

  3. Asigne al proyecto el nombre ASPHello y haga clic en Aceptar.

  4. Quite los comentarios de línea en el archivo Service1.asmx.cs que contiene System.Web.Script.Services.ScriptService] para habilitar AJAX en este servicio.

  5. En el menú Generar, seleccione Generar solución.

  6. En el menú Depurar, seleccione Iniciar sin depurar.

  7. En la página web generada, seleccione la operación HelloWorld.

  8. Haga clic en el botón Invocar en la página de prueba de HelloWorld. Debería recibir la siguiente respuesta XML.

    <?xml version="1.0" encoding="utf-8" ?>
    <string xmlns="http://tempuri.org/">Hello World</string>
    
  9. Esta respuesta confirma que ha recibido un servicio de AJAX de ASP.NET que funciona y, en particular, que el servicio ha expuesto un extremo en Service1.asmx/HelloWorld que responde a la solicitud HTTP POST y devuelve XML.

    Para obtener más información acerca de cómo obtener acceso a este servicio, consulte Using Web Services in ASP.NET AJAX.

    Ahora ya puede convertir este servicio para utilizar un servicio de AJAX de WCF.

Para crear una aplicación de servicio de AJAX de WCF equivalente.

  1. Haga clic con el botón secundario en el proyecto ASPHello y seleccione Agregar, Nuevo elemento, y Servicio WCF con AJAX habilitado.

  2. Denomine al servicio como WCFHello y haga clic en Agregar.

  3. Abra el archivo WCFHello.svc.cs.

  4. En Service1.asmx.cs, copie la siguiente implementación de la operación HelloWorld.

    public string HelloWorld()
    {
         return "Hello World";
    }
    
  5. Pegue la implementación copiada de la operación HelloWorld en el archivo WCFHello.svc.cs en vez del código siguiente.

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

    [ServiceContract(Namespace="WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class WCFHello
    { … }
    
  7. Agregue WebInvokeAttribute a la operación HelloWorld y establezca la propiedad RequestFormat para devolver Xml. Observe que, si no se establece, el tipo devuelto predeterminado es Json.

            [OperationContract]
            [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
            public string HelloWorld()
            {
                return "Hello World";
            }
    
  8. En el menú Generar, seleccione Generar solución.

  9. Abra al archivo WCFHello.svc.cs y en el menú Depurar, seleccione Iniciar sin depurar.

  10. El servicio expone un extremo en WCFHello.svc/HelloWorld, que responde a la solicitudes HTTP POST. Las solicitudes HTTP POST no se pueden probar desde el explorador, pero los extremos devuelven XML a continuación de XML.

    <string xmlns="https://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
    
  11. Los extremos WCFHello.svc/HelloWorld y Service1.aspx/HelloWorld funcionan de forma equivalente.

Ejemplo

El código resultado del procedimiento descrito en este tema se proporciona en el ejemplo siguiente.

//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].
    }
}

El tipo XmlDocument no es compatible con DataContractJsonSerializer porque no es serializable por XmlSerializer. Puede utilizar un tipo XDocument o serializar DocumentElement en su lugar.

Si los servicios web de ASMX se están actualizando y migrando, de manera paralela a los servicios WCF, evite asignar dos tipos al mismo nombre en el cliente. Esto produce una excepción en los serializadores si el mismo tipo se utiliza en WebMethodAttribute y ServiceContractAttribute:

  • Si se agrega primero el servicio WCF, que invoca al método en el servicio web ASMX produce una excepción en ConvertValue porque la definición de estilo de WCF de orden en el proxy tiene prioridad.
  • Si se agrega primero el servicio web ASMX, el método de invocación en el servicio WCF produce una excepción en DataContractJsonSerializer porque la definición de estilo del servicio web de orden en el proxy tiene prioridad.

Hay diferencias significativas en el comportamiento entre DataContractJsonSerializer y el AJAX de ASP.NET JavascriptSerializer. Por ejemplo, DataContractJsonSerializer representa un diccionario como una matriz de pares de clave y valor, mientras que el JavascriptSerializer de AJAX de ASP.NET representa un diccionario como objetos JSON reales. Por tanto lo siguiente es el diccionario representado en ASP.NET AJAX.

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

Este diccionario se representa en objetos JSON como se muestra en la siguiente lista:

  • [{"Clave":"uno","Valor":1}, {"Clave":"dos","Valor":2}] por DataContractJsonSerializer
  • {"uno":1, "dos":2} por el JavascriptSerializer de AJAX de ASP.NET

DataContractJsonSerializer es más eficaz en el sentido de que puede administrar los diccionarios donde el tipo de clave no es de cadena, mientras que JavascriptSerializer no puede. Pero el último es más compatible con JSON.

Las diferencias significativas entre estos serializadores se resumen en la siguiente tabla.

Categoría de diferencias DataContractJsonSerializer JavaScriptSerializer de AJAX de ASP.NET

Deserializar el búfer vacío (nuevo byte [0]) en Object (o Uri o algunas otras clases).

SerializationException

null

Serialización de Value

{} (or {"__type":"#System"})

Null

Serialización de los miembros privados de tipos [Serializable].

serialized

not serialized

Serialización de las propiedades públicas de los tipos ISerializable.

not serialized

serialized

"Extensiones" de JSON

Conforme con la especificación de JSON, que requiere comillas en los nombres de miembro de objetos ({"a":"hola"}).

Admite los nombres de miembros de objeto sin comillas ({a:"hola"}).

DateTimeHora universal coordinada (UTC)

No admite el formato "\/Fecha (123456789U) \/" o "\/Date\(\d + (U | (\+ \- [\d {4}]))?\)\\/)".

Admite el formato "\/Fecha (123456789U) \/" y "\/Date\(\d + (U | (\+ \- [\d {4}]))? \) \\/) " como valores DateTime.

Representación de diccionarios

Una matriz de KeyValuePair<K,V>, administra tipos clave que no son cadenas.

Como objetos JSON reales, pero sólo controla los tipos clave que son cadenas.

Caracteres con escape

Siempre con una barra diagonal de escape (/); nunca permite caracteres de JSON no válidos sin escape, como "\n".

Con una barra diagonal de escape (/) para los valores DateTime .

Consulte también

Tareas

Uso de la configuración para agregar un extremo AJAX de ASP.NET