Condividi tramite


Procedura: eseguire la migrazione di servizi Web ASP.NET compatibili AJAX a WCF

In questo argomento vengono descritte le procedure per eseguire la migrazione di un servizio AJAX di base ASP.NET a un servizio Windows Communication Foundation (WCF) abilitato per AJAX equivalente. Verrà descritto come creare una versione WCF funzionalmente equivalente a un servizio ASP.NET.AJAX. I due servizi possono quindi essere utilizzati in modo affiancato, oppure il servizio WCF può essere utilizzato al posto del servizio ASP.NET.AJAX.

La migrazione di un servizio ASP.NET.AJAX esistente in un servizio AJAX WCF offre i vantaggi seguenti:

  • È possibile esporre il servizio AJAX come servizio SOAP tramite una minima configurazione aggiuntiva.

  • Sarà possibile usufruire delle funzionalità di WCF quali la traccia e così via.

Ai fini delle procedure seguenti si presuppone che venga utilizzato Visual Studio 2012.

Il codice generato dalle procedure descritte in questo argomento viene fornito nell'esempio riportato dopo le procedure stesse.

Per altre informazioni sull'esposizione di un servizio WCF tramite un endpoint compatibile con AJAX, vedere l'argomento Procedura: Aggiungere un endpoint ASP.NET AJAX con l'uso della configurazione.

Per creare e testare l'applicazione del servizio Web ASP.NET

  1. Aprire Visual Studio 2012.

  2. Dal menu File selezionare Nuovo, quindi Progetto, Web e quindi selezionare Applicazione del servizio Web ASP.NET.

  3. Assegnare un nome ASPHello al progetto e fare clic su OK.

  4. Rimuovere il commento dalla riga nel file Service1.asmx.cs che contiene System.Web.Script.Services.ScriptService] per abilitare AJAX per questo servizio.

  5. Dal menu Compila scegliere Compila soluzione.

  6. Dal menu Debug, selezionare Avvia senza eseguire debug.

  7. Nella pagina Web generata, selezionare l'operazione HelloWorld.

  8. Fare clic sul pulsante Richiama nella pagina di prova di HelloWorld. Si dovrebbe ricevere la risposta XML seguente:

    <?xml version="1.0" encoding="utf-8" ?>
    <string xmlns="http://tempuri.org/">Hello World</string>
    
  9. Questa risposta conferma che si dispone di un servizio ASP.NET.AJAX funzionante e, in particolare, che il servizio ha esposto un endpoint su Service1.asmx/HelloWorld che risponde alle richieste HTTP POST e restituisce XML.

    È ora possibile convertire il servizio per utilizzare un servizio AJAX WCF.

Per creare un'applicazione di servizio AJAX WCF equivalente

  1. Fare clic con il pulsante destro del mouse sul progetto ASPHello e scegliere Aggiungi, quindi Nuovo elemento e infine Sevizio WCF compatibile AJAX.

  2. Assegnare un nome WCFHello al servizio e fare clic su Aggiungi.

  3. Aprire il file WCFHello.svc.cs.

  4. Da Service1.asmx.cs, copiare l'implementazione seguente dell'operazione HelloWorld.

    public string HelloWorld()
    {
        return "Hello World";
    }
    
  5. Incollare l'implementazione copiata dell'operazione HelloWorld nel file WCFHello.svc.cs al posto del codice seguente.

    public void DoWork()
    {
          // Add your operation implementation here
          return;
    }
    
  6. Specificare l'attributo Namespace per ServiceContractAttribute come WCFHello.

    [ServiceContract(Namespace="WCFHello")]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class WCFHello
    { … }
    
  7. Aggiungere WebInvokeAttribute all'operazione di HelloWorld e impostare la proprietà ResponseFormat in modo da restituire Xml. Se non impostato, il tipo restituito predefinito è Json.

    [OperationContract]
    [WebInvoke(ResponseFormat=WebMessageFormat.Xml)]
    public string HelloWorld()
    {
        return "Hello World";
    }
    
  8. Dal menu Compila scegliere Compila soluzione.

  9. Aprire il file WCFHello.svc e selezionare Avvia senza eseguire debug dal menu Debug.

  10. Il servizio esporrà un endpoint su WCFHello.svc/HelloWorld, che risponde alle richieste HTTP POST. Le richieste HTTP POST non possono essere sottoposte a test dal browser, ma l'endpoint restituisce l'XML seguente.

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
    
  11. WCFHello.svc/HelloWorld e gli endpoint Service1.aspx/HelloWorld ora sono equivalenti a livello funzionale.

Esempio

Il codice che scaturisce dalle procedure descritte in questo argomento viene fornito nell'esempio seguente.

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

Il tipo XmlDocument non è supportato da DataContractJsonSerializer perché non è serializzabile mediante XmlSerializer. È possibile utilizzare un tipo XDocument oppure serializzare DocumentElement.

Se l'aggiornamento/migrazione dei servizi Web ASMX vengono eseguiti side-by-side ai servizi WCF, evitare di eseguire il mapping di due tipi allo stesso nome sul client. Se viene utilizzato lo stesso tipo sia in un WebMethodAttribute che in un ServiceContractAttribute, nei serializzatori verrà generata un'eccezione:

  • Se viene aggiunto per primo un servizio WCF, la chiamata del metodo sul servizio Web ASMX provoca un'eccezione in ConvertValue(Object, Type, String) perché la definizione di stile di WCF dell'ordine nel proxy ha la precedenza.

  • Se viene aggiunto per primo un servizio Web ASMX, la chiamata del metodo sul servizio WCF provoca un'eccezione in DataContractJsonSerializer perché la definizione di stile del servizio Web dell'ordine nel proxy ha la precedenza.

Esistono differenze significative di comportamento tra DataContractJsonSerializer e JavaScriptSerializer ASP.NET AJAX. DataContractJsonSerializer, ad esempio, rappresenta un dizionario come una matrice di coppie chiave/valore, mentre ASP.NET AJAX JavaScriptSerializer rappresenta un dizionario come oggetti JSON effettivi. Pertanto quello seguente è il dizionario rappresentato in ASP.NET AJAX.

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

Tale dizionario è rappresentato negli oggetti JSON come mostrato nell'elenco seguente:

DataContractJsonSerializer è più potente perché può gestire dizionari in cui il tipo di chiave non è una stringa, mentre JavaScriptSerializer non è in grado di farlo. Quest'ultimo, tuttavia, è più favorevole a JSON.

Le differenze significative tra questi serializzatori sono riepilogate nella tabella seguente.

Categoria delle differenze DataContractJsonSerializer JavaScriptSerializer per ASP.NET AJAX
Deserializzazione del buffer vuoto (new byte[0]) in Object (o Uri o alcune altre classi). SerializationException Null
Serializzazione di Value {} (o {"__type":"#System"}) Null
Serializzazione dei membri privati di tipi [Serializable]. serializzato non serializzato
Serializzazione delle proprietà pubbliche di tipi ISerializable. non serializzato serializzato
"Estensioni" di JSON È conforme alla specifica JSON, che richiede le virgolette per i nomi dei membri di un oggetto ({"a":"hello"}). Supporta i nomi dei membri di un oggetto senza virgolette ({a:"hello"}).
Ora UTC (Coordinated Universal Time) DateTime Non supporta il formato "\/Date(123456789U)\/" or "\/Date\(\d+(U|(\+\-[\d{4}]))?\)\\/)". Supporta il formato "\/Date(123456789U)\/" e "\/Date\(\d+(U|(\+\-[\d\{4}]))?\)\\/)" come valori DateTime.
Rappresentazione di dizionari Una matrice di KeyValuePair <K, V>, gestisce tipi di chiave che non sono stringhe. Come gli oggetti JSON effettivi, ma gestisce solo i tipi di chiave che sono stringhe.
Caratteri di escape Sempre con un carattere di escape barra (/); non consente mai caratteri JSON non validi senza carattere di escape, ad esempio "\n". Con un carattere di escape barra (/) per i valori DateTime.

Vedi anche