Procedura: eseguire la migrazione di servizi Web ASP.NET compatibili AJAX a WCF
In questo argomento vengono illustrate le procedure per eseguire la migrazione di un servizio ASP.NET AJAX di base a un servizio Windows Communication Foundation (WCF) compatibile 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 2008.
Il codice generato dalle procedure descritte in questo argomento viene fornito nell'esempio riportato dopo le procedure stesse.
Per ulteriori 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'utilizzo della configurazione.
Per creare e testare l'applicazione del servizio Web ASP.NET
Aprire Visual Studio 2008.
Scegliere Nuovo dal menu File, quindi Progetto, Web e infine Applicazione servizio Web ASP.NET.
Assegnare al progetto il nome ASPHello, quindi fare clic su OK.
Rimuovere il commento dalla riga nel file Service1.asmx.cs che contiene
System.Web.Script.Services.ScriptService]
per abilitare AJAX per questo servizio.Scegliere Compila soluzione dal menu Compila.
Scegliere Avvia senza eseguire debug dal menu Debug.
Nella pagina Web generata, selezionare l'operazione
HelloWorld
.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>
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.
Per ulteriori informazioni su come accedere al servizio, vedere Using Web Services in ASP.NET AJAX.
È ora possibile convertire il servizio per utilizzare un servizio AJAX WCF.
Per creare un'applicazione di servizio AJAX WCF equivalente
Fare clic con il pulsante destro del mouse sul progetto ASPHello e scegliere Aggiungi, quindi Nuovo elemento e infine Sevizio WCF compatibile AJAX.
Assegnare al servizio il nome WCFHello, quindi fare clic su Aggiungi.
Aprire il file WCFHello.svc.cs.
Da Service1.asmx.cs, copiare l'implementazione seguente dell'operazione HelloWorld.
public string HelloWorld() { return "Hello World"; }
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; }
Specificare l'attributo Namespace per ServiceContractAttribute come WCFHello.
[ServiceContract(Namespace="WCFHello")] [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)] public class WCFHello { … }
Aggiungere WebInvokeAttribute all'operazione HelloWorld e impostare la proprietà RequestFormat affinché restituisca Xml. Se non impostato, il tipo restituito predefinito è Json.
[OperationContract] [WebInvoke(ResponseFormat=WebMessageFormat.Xml)] public string HelloWorld() { return "Hello World"; }
Scegliere Compila soluzione dal menu Compila.
Aprire il file WCFHello.svc e selezionare Avvia senza eseguire debug dal menu Debug.
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="https://schemas.microsoft.com/2003/10/Serialization/">Hello World</string>
WCFHello.svc/HelloWorld e gli endpoint Service1.aspx/HelloWorld sono ora funzionalmente equivalenti.
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 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:
- [{"Key":"one","Value":1},{"Key":"two","Value":2}] da DataContractJsonSerializer
- {“one”:1,”two”:2} da JavascriptSerializer ASP.NET AJAX.
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)\/" o "\/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. |
Vedere anche
Attività
Procedura: aggiungere un endpoint ASP.NET AJAX con l'utilizzo della configurazione