Il presente articolo è stato tradotto automaticamente.
ASP.NET,
La migrazione ASP.NET Web Form al Pattern MVC con ASP.NET Web API
Mentre ASP.NET MVC tende ad ottenere la maggior parte dell'attenzione in questi giorni, ASP.NET Web Form e i relativi controlli correlati consentono agli sviluppatori di generare interfacce utente potente, interattive, in un breve periodo di tempo — che è perché ci sono così tante applicazioni Web Form ASP.NET intorno. Che cosa non supporta ASP.NET Web Form implementa il pattern Model-View-Controller (MVC) e Model-View-ViewModel (MVVM), che può attivare il test-driven development (TDD).
Il ASP.NET Web API ("Web API" hereafter) fornisce un modo per costruire o effettuare il refactoring di applicazioni Web Form ASP.NET per il pattern MVC spostando il codice dal file code-behind a un controller di Web API. Questo processo consente anche applicazioni ASP.NET leva Asynchronous JavaScript and XML (AJAX), che può essere utilizzato per creare un'interfaccia utente più reattiva e migliorare la scalabilità di un'applicazione logica in movimento nel client e riducendo la comunicazione con il server. Questo è possibile perché l'API Web sfrutta il protocollo HTTP e (attraverso la codificazione di convenzione) automaticamente si occupa di diverse attività di basso livello. Il paradigma Web API per ASP.NET che propone questo articolo è lasciato ASP.NET per generare il set iniziale di markup inviato al browser, ma gestire tutte le interazioni dell'utente tramite AJAX chiama in un autonomo, controller testabile.
Configurazione dell'infrastruttura di avere un'applicazione Web Form di interagire con il server attraverso una serie di chiamate AJAX non è difficile. Ma io non indurre in errore: Refactoring di codice nel file di codice dell'applicazione Web Form per lavorare in un controller di Web API potrebbe non essere un compito banale. Devi rinunciare ai vari eventi licenziati dai controlli, auto-generato di convalida sul lato server e ViewState. Tuttavia, come si vedrà, ci sono alcune soluzioni per vivere senza queste caratteristiche che possono ridurre il dolore.
Aggiunta di infrastruttura Web API
Per utilizzare l'API di Web in un progetto ASP.NET , tutto quello che devi fare (dopo aver aggiunto il pacchetto NuGet ASP.NET Web API di Microsoft) è il tasto destro del mouse e selezionare Aggiungi | Nuovo elemento | Classe Controller API Web. Se non si vede la classe di Controller API Web nella finestra di dialogo, assicurarsi che avete installato il pacchetto Microsoft NuGet ASP.NET Web API, e che si seleziona Web dagli elementi sotto il linguaggio di programmazione desiderato. Tuttavia, aggiunge il controller in questo modo viene creata una classe con un sacco di codice di default che ti basta eliminare successivamente. Si potrebbe preferire semplicemente aggiungere un file di classe ordinaria e lo hanno eredita dalla classe System.Web.Http.ApiController. Per lavorare con l'infrastruttura di routing ASP.NET , il nome della classe deve terminare con la stringa "Controller".
Questo esempio crea un controller Web API denominato Customer:
public class CustomerController : ApiController
{
Una classe controller Web API supporta una grande quantità di codifica dalla convenzione. Ad esempio, per avere un metodo chiamato ogni volta che un modulo viene inviato al server, bisogno hai solo un metodo denominato "Post" o con un nome che inizia con "Post" (sotto il cofano, una pagina che il retro inviato al server viene inviato al server con il verbo HTTP POST; l'API Web raccoglie i metodi basati sul verbo HTTP della richiesta). Se quel nome metodo viola l'organizzazione di codifica convenzione, è possibile utilizzare l'attributo HttpPost per bandiera il metodo da utilizzare quando i dati viene inviati al server. Il codice seguente crea un metodo chiamato UpdateCustomer nel controller cliente di gestire i messaggi HTTP:
public class CustomerController : ApiController
{
[HttpPost]
public void UpdateCustomer()
{
Post metodi accettano, al massimo, un solo parametro (un metodo post con più parametri viene ignorato). I dati più semplici che possono essere inviati a un metodo post sono un singolo valore nel corpo del post, preceduti da un segno di uguale (per esempio, "= ALFKI"). L'API Web mapperà automaticamente che dati all'unico parametro del metodo post, fornito il parametro è decorato con l'attributo FromBody, come in questo esempio:
[HttpPost]
public HttpResponseMessage UpdateCustomer([FromBody] string CustID)
{
Questo è, naturalmente, quasi inutile. Se si desidera registrare più di un singolo valore — i dati da un modulo Web, ad esempio, sarà necessario definire una classe per contenere i valori del Web Form: un oggetto di trasferimento dati (DTO). Gli standard di convenzione codifica Web API aiutare qui. È solo necessario definire una classe con i nomi di proprietà che corrispondono ai nomi associati con i controlli Web Form per avere il vostro Proprietà DTO automaticamente popolata con i dati del Web Form dall'API Web.
Un esempio di dati che possono essere inviati indietro a un controller di Web API, l'esempio (certamente semplice) Web Form mostrato Figura 1 ha solo tre caselle di testo, un RequiredFieldValidator e un pulsante.
Figura 1 esempio base Web Form
<form id="form1" runat="server">
<p>
Company Id: <asp:TextBox ID="CustomerID"
ClientIDMode="Static" runat="server">
</asp:TextBox> <br/>
Company Name: <asp:TextBox ID="CompanyName"
ClientIDMode="Static" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ControlToValidate="CompanyName"
Display="Dynamic"
ErrorMessage="Company Name must be provided">
</asp:RequiredFieldValidator><br/>
City: <asp:TextBox ID="City"
ClientIDMode="Static" runat="server">
</asp:TextBox><br/>
</p>
<p>
<asp:Button ID="PostButton" runat="server" Text="Update" />
</p>
</form>
Per accettare i dati dalle caselle di testo in questo modulo Web il metodo post, si creerà una classe con proprietà con nomi che corrispondono alle proprietà ID di caselle di testo, come fa questa classe (tutti i controlli nel Form Web che non hanno una proprietà corrispondente vengono ignorati dall'API Web):
public class CustomerDTO
{
public string CustomerID { get; set; }
public string CompanyName { get; set; }
public string City { get; set; }
}
Una forma più complessa del Web potrebbe richiedere un DTO che non può vivere con (o è oltre le capacità dell'API Web da associare alla). Se è così, è possibile creare il proprio modello Binder per mappare i dati dai controlli Web Form per le proprietà DTO. In uno scenario di refactoring, il codice nel Form Web sarà già lavorare con i nomi dei controlli ASP.NET — avendo proprietà su DTO identicamente denominate riduce il lavoro richiesto quando si sposta quel codice nel controller Web API.
Il modulo Web di routing
Il passo successivo nell'integrare le API di Web in un ciclo di elaborazione dei Web Form ASPX è di fornire una regola di routing nell'evento Application_Start del file Global. asax dell'applicazione che dirigerà il postback del form al tuo controller. Una regola di routing è costituito da un modello che specifica l'URL a cui si applica la regola e quale controller è di gestire la richiesta. Il modello specifica anche dove nell'URL per individuare i valori che devono essere utilizzati dall'API Web (inclusi i valori da passare ai metodi nel controller).
Ci sono alcune pratiche standard che possono essere ignorati. La regola di routing standard può corrispondere a quasi qualsiasi URL, che può portare a risultati imprevisti quando la regola viene applicata per gli URL che non intendete la regola per essere utilizzato con. Per evitare che, Microsoft consiglia di avere gli URL associati con l'API Web iniziano con la stringa "api" per evitare collisioni con gli URL utilizzati altrove nell'applicazione. Quel "api" non esegue nessun altra funzione utile e pastiglie appena fuori tutti i tuoi URL.
Che mettere insieme, si finisce con una generalizzata regola di routing nell'evento Application_Start che assomiglia a questo (è necessario aggiungere le istruzioni using System.Web.Routing sia System.Web.Http per il Global. asax per sostenere questo codice):
RouteTable.Routes.MapHttpRoute(
"API Default",
"api/{controller}/{id}",
new { id = RouteParameter.Optional })
);
Questo instradamento estrae il nome del controller dal secondo parametro del modello, così gli URL diventano strettamente collegati al controller. Se si rinomina il controller, qualsiasi client utilizzando l'URL di smettere di lavorare. (Anche io preferisco che eventuali parametri mappati nell'URL dal modello hanno nomi più significativi rispetto a "id.") Sono venuto a preferire le regole di routing più specifici che non richiedono il nome del controller nel modello, ma, invece, specificare il nome del controller in default passati nel terzo parametro al metodo MapHttpRoute. Rendendo i modelli nelle mie regole di routing più specifici, anche bypassare la necessità di un prefisso speciale per gli URL utilizzati con controllori Web API, e meno frequentemente sono sorpreso dai risultati delle mie regole di routing.
Le mie regole di routing assomigliano il codice seguente, che crea un percorso chiamato CustomerManagementPost che si applica solo agli URL inizia con "CustomerManagement" (in seguito il nome del server e il sito):
RouteTable.Routes.MapHttpRoute(
"CustomerManagementPost",
"CustomerManagement",
new { Controller = "Customer" },
new { httpMethod = new HttpMethodConstraint("Post") }
);
Questa regola sarebbe, per esempio, si applicano solo a un URL come www.phivs.com/CustomerManagement. Nelle impostazioni predefinite, legare questo URL per il controller del cliente. Solo per assicurarsi che il percorso viene utilizzato solo quando si intendo, io uso il quarto parametro per specificare che questo percorso deve essere utilizzato solo quando i dati viene inviati indietro come un HTTP POST.
Refactoring per il Controller
Se stai refactoring di un modulo Web esistente, il passo successivo è quello di ottenere il modulo Web per inviare i dati a questo itinerario appena definito piuttosto che torna a se stesso. Questo è il primo cambiamento al codice esistente — tutto altro fatto finora è stato aggiunto il codice, lasciando elaborazione esistenti nel luogo. Il tag form rivisto dovrebbe essere qualcosa come questo:
<form id="form1" runat="server" action="CustomerManagement"
method="post" enctype="application/x-www-form-urlencoded">
Il cambio di tonalità è l'impostazione di attributo action del tag form da utilizzare l'URL specificato nell'itinerario ("CustomerManagement"). Gli attributi del metodo ed enctype garantiscono la compatibilità cross-browser. Quando la pagina postback il controller, l'API Web verrà automaticamente chiamare il metodo post, un'istanza della classe passata al metodo e mappa dati dal Web Form per le proprietà su DTO — e quindi passare il DTO per il metodo post.
Con tutti i pezzi a posto, ora è possibile scrivere codice nel metodo post del tuo controller per lavorare con i dati in DTO. Il codice seguente aggiorna un oggetto di entity Entity Framework corrispondente per un modello basato sul database Northwind utilizzando i dati passati dal Form Web:
[HttpPost]
public void UpdateCustomer(CustomerDTO custDTO)
{
Northwind ne = new Northwind();
Customer cust = (from c in ne.Customers
where c.CustomerID == custDTO.CustomerID
select c).SingleOrDefault();
if (cust != null)
{
cust.CompanyName = custDTO.CompanyName;
}
ne.SaveChanges();
Quando l'elaborazione è completa, qualcosa deve essere inviato al client. Inizialmente, appena tornerò un oggetto HttpResponseMessage configurato per reindirizzare l'utente a un'altra pagina ASPX del sito (a seguito del refactoring migliorerà questo). In primo luogo, è necessario modificare il metodo post per restituire un HttpResponseMessage:
[HttpPost]
public HttpResponseMessage UpdateCustomer(CustomerDTO custDTO)
Quindi è necessario aggiungere il codice alla fine del metodo che restituisce la risposta di reindirizzamento al client:
HttpResponseMessage rsp = new HttpResponseMessage();
rsp.StatusCode = HttpStatusCode.Redirect;
rsp.Headers.Location = new Uri("RecordSaved.aspx", UriKind.Relative);
return rsp;
}
Il vero lavoro inizia adesso, tra cui:
- Qualunque codice era nel file di codice ASPX nel nuovo metodo del controller in movimento
- Aggiunta in ogni lato server convalida eseguita dai controlli di convalida
- Scollegando il codice dagli eventi licenziato dalla pagina
Questi non sono compiti banali. Tuttavia, come si vedrà, avete alcune opzioni che potrebbero semplificare questo processo continuando ad AJAX -attivare la pagina. Una di queste opzioni, infatti, permette di lasciare codice di Web Form se non può essere spostato al controller (o se si vuole essere spostato più avanti).
A questo punto in un modulo Web esistente di refactoring, hai spostato al pattern MVC, ma voi non avete spostato al paradigma AJAX. La pagina è ancora utilizzando il ciclo classico di richiesta/risposta piuttosto che eliminando il postback della pagina. Il passo successivo è quello di creare una pagina veramente AJAX-enabled.
Trasferirsi in AJAX
Il primo passo per eliminare il ciclo di richiesta/risposta è inserire il processo alcuni JavaScript impostando la proprietà OnClientClick del pulsante per chiamare una funzione client-side. Questo esempio ha il tasto chiamata una funzione JavaScript denominata UpdateCustomer:
<asp:Button ID="PostButton" runat="server" Text="Update"
OnClientClick="return UpdateCustomer();" />
In questa funzione, potrai intercettare il postback attivato dall'utente facendo clic sul pulsante e sostituirlo con una chiamata AJAX al metodo del servizio. Utilizzando la parola chiave return in OnClientClick e avendo UpdateCustomer restituire false sopprimerà il postback attivato dal pulsante. La funzione intercetta dovrebbe richiamare anche qualsiasi codice di convalida lato client generato dai controlli di convalida ASP.NET chiamando il ASP.NET-fornito Page_ClientValidate funzione (in un processo di refactoring, chiamata codice client-side dei validatori potrebbe farvi evitare di dover ricreare la convalida sul lato server dei validatori).
Se stai refactoring di un modulo Web esistente, è ora possibile rimuovere l'attributo action su tag form che utilizza il vostro itinerario. Rimuovere l'attributo action consente di implementare un approccio ibrido/in scena per lo spostamento di codice del modulo Web al vostro controller Web API. Per il codice che non si vuole spostare il controller (ancora), è possibile continuare a lasciare che il Web Form post torna a se stesso. Ad esempio, nella funzione intercetta, è possibile controllare per vedere quali modifiche hanno avuto luogo nel Web Form e restituiscono true dalla funzione INTERCETTA per far continuare il postback. Se ci sono più controlli sulla pagina che attivano i postback, è possibile scegliere quali controlli si desidera elaborare nel tuo controller Web API e scrivere funzioni intercetta solo per quelli. Questo consente di implementare un approccio ibrido quando refactoring (lasciando qualche codice di Web Form) o un approccio graduale (la migrazione del codice nel tempo).
Il UpdateMethod ora ha bisogno di chiamare il servizio di Web API a cui la pagina è stata precedentemente distacco posteriore. Aggiunta di jQuery per il progetto e la pagina (ho usato jQuery 1.8.3) consente di utilizzare la sua funzione di post per chiamare il vostro servizio Web API. JQuery serializzare funzione converte la forma in un insieme di coppie nome/valore che l'API di Web mapping ai nomi delle proprietà dell'oggetto CustomerDTO. Integrare questa chiamata la funzione UpdateCustomer — affinché il post succede solo se non vengono rilevati errori nessun client-side — dà questo codice:
function UpdateCustomer() {
if (Page_ClientValidate()){
$.post('CustomerManagement', $('#form1').serialize())
.success(function () {
// Do something to tell the user that all went well.
})
.error(function (data, msg, detail) {
alert(data + '\n' + msg + '\n' + detail)
});
}
return false;
}
La serializzazione il modulo Invia un sacco di dati al controller, non tutti di cui potrebbe essere necessari (per esempio, il ViewState). Vi guiderò attraverso l'invio solo i dati necessari più avanti in questo articolo.
Il passaggio finale (almeno per questo semplice esempio) è quello di riscrivere la fine del metodo post nel controller così l'utente rimane nella pagina corrente. Questa versione del metodo post restituisce solo un stato HTTP OK utilizzando la classe HttpResponseMessage:
...
ne.SaveChanges();
HttpResponseMessage rsp = new HttpResponseMessage();
rsp.StatusCode = HttpStatusCode.OK;
return rsp;
}
Elaborazione del flusso di lavoro
Ora dovete decidere dove dovrebbero trovarsi le responsabilità per l'ulteriore elaborazione. Come indicato in precedenza, se l'utente deve essere inviata a una pagina diversa, è possibile gestire che nel vostro controller. Tuttavia, se il controller è ora solo restituendo un messaggio OK al client, è possibile eseguire alcune elaborazioni aggiuntive nel client. Ad esempio, aggiungere un'etichetta al Form Web per visualizzare il risultato dell'elaborazione sul lato server sarebbe un buon inizio:
Stato di aggiornamento: < asp: Label ID = "Messaggi" runat = "server" Testo = "" >< / asp: Label >
Nel metodo di successo per la chiamata AJAX, si dovrebbe aggiornare l'etichetta con lo stato della vostra chiamata AJAX:
success: function (data, status) {
$("#Messages").text(status);
},
Non è insolito, come parte dell'elaborazione di una pagina inviata, per il codice lato server del Web Form aggiornare i controlli nella pagina prima di ritornare alla pagina dell'utente. Per gestire questo, sarà necessario restituire dati dal metodo post di servizio e aggiornare la pagina dal tuo funzione JavaScript.
Il primo passo in questo processo è quello di impostare la proprietà Content dell'oggetto HttpResponseMessage per contenere i dati che tu stai tornando. Perché il DTO creato per passare dati al post Metodo dal modulo è già disponibile, ha senso utilizzarlo per inviare i dati al client. Tuttavia, non c'è è necessario contrassegnare la classe con l'attributo Serializable ad usarlo con l'API Web DTO. (In realtà, se si contrassegna il DTO con l'attributo Serializable, i campi sottostanti per le proprietà DTO saranno essere serializzati e inviati al client, dandovi strani nomi a lavorare con la versione client-side di DTO.)
Questo codice aggiorna la proprietà DTO città e si muove per la proprietà di contenuto HttpResponseMessage, formattata come un oggetto JSON (sarà necessario aggiungere un utilizzo istruzione per System.Net.Http.Headers al vostro controller per rendere questo codice funziona):
HttpResponseMessage rsp = new HttpResponseMessage();
rsp.StatusCode = HttpStatusCode.OK;
custDTO.City = cust.City;
rsp.Content = new ObjectContent<CustomerDTO>(custDTO,
new JsonMediaTypeFormatter(),
new MediaTypeWithQualityHeaderValue("application/json"));
Il passo finale è quello di migliorare la funzione INTERCETTA per avere il suo metodo di successo spostare i dati in forma:
.success(function (data, status) {
$("#Messages").text(status);
if (status == "success") {
$("#City").val(data.City);
}
})
Questo codice non, naturalmente, aggiorna il ViewState ASP.NET . Se la pagina in seguito post indietro nel modo normale ASP.NET , TextBox città attiverà un evento TextChanged. Se non c'è codice nel codice lato server del Form Web legato a quell'evento, si potrebbe finire con conseguenze impreviste. Se stai facendo una migrazione graduale o utilizzando un approccio ibrido, è necessario testare per questo. In una versione completamente implementata del paradigma, dove il Web Form non è inviato al server dopo la visualizzazione iniziale, questo non è un problema.
Sostituzione di eventi
Come osservato in precedenza, si sta andando ad avere per vivere senza gli eventi lato server ASP.NET . Tuttavia, è invece possibile acquisire l'evento JavaScript equivalente che innesca il postback al server e richiamare un metodo sul vostro servizio che fa ciò che vuoi hai fatto il codice nell'evento sul lato server. Un graduale processo di refactoring sfrutta questo, consentendo di eseguire la migrazione di questi eventi quando hanno il tempo (o si sentono la necessità).
Ad esempio, se la pagina ha un pulsante Elimina per eliminare il cliente attualmente visualizzato, è possibile lasciare la funzionalità nel file di codice della pagina come parte della migrazione iniziale — appena lasciate il pulsante delete post della pagina al server. Quando si è pronti per migrare la funzione di cancellazione, iniziare con l'aggiunta di una funzione per intercettare l'evento lato client onclick del pulsante Elimina. In questo esempio, ho scelto di associare l'evento in JavaScript — una tattica che funziona con qualsiasi evento lato client:
<asp:Button ID="DeleteButton" runat="server" Text="Delete" />
<script type="text/javascript">
$(function () {
$("#DeleteButton").click(function () { return DeleteCustomer() });
})
Nella funzione DeleteCustomer, anziché serializzare l'intera pagina, potrai inviare solo i dati necessari dal server-side Metodo delete: il CustomerID. Perché posso incorporare quel singolo parametro nell'URL utilizzato per richiedere il servizio, questo mi permette utilizzare un altro uno dei verbi HTTP standard per selezionare il metodo corretto controller: Elimina (per ulteriori informazioni su verbi HTTP, vedere bit.ly/92iEnV).
Utilizzando la funzione ajax di jQuery, io posso emettere una richiesta al mio controller, costruendo l'URL con i dati dalla pagina e specificando che l'HTTP eliminare il verbo deve essere utilizzato come tipo di richiesta (vedere Figura 2).
Figura 2 utilizzando la funzionalità AJAX jQuery per emettere una richiesta di Controller
function DeleteCustomer() {
$.ajax({
url: 'CustomerManagement/' + $("#CustomerID").val(),
type: 'delete',
success: function (data, status) {
$("#Messages").text(status);
},
error: function (data, msg, detail) {
alert(data + '\n' + msg + '\n' + detail)
}
});
return false;
}
Il passo successivo è quello di creare una regola di routing che identifica quale parte dell'URL contiene il CustomerID e assegnare tale valore a un parametro (in questo caso, un parametro denominato CustID):
RouteTable.Routes.MapHttpRoute(
"CustomerManagementDelete",
"CustomerManagement/{CustID}",
new { Controller = "Customer" },
new { httpMethod = new HttpMethodConstraint("Delete") }
);
Come con il post, l'API Web instraderà automaticamente una richiesta HTTP DELETE a un metodo del controller denominato o inizio con "Delete" — o a un metodo contrassegnato con l'attributo HttpDelete. E, come prima, l'API Web verrà automaticamente mappa qualsiasi dati estratti dall'URL di parametri sul metodo che corrispondano al nome del modello:
[HttpDelete]
public HttpResponseMessage FlagCustomerAsDeleted(string CustID)
{
//...
Code to update the Customer object ...
HttpResponseMessage rsp = new HttpResponseMessage();
rsp.StatusCode = HttpStatusCode.OK;
return rsp;
}
Di là dei verbi HTTP
La maggior parte delle pagine ASP.NET non erano progettate con i verbi HTTP in mente; invece, un approccio "transazionale" è stato spesso utilizzato nel definire la versione originale del codice. Questo può rendere difficile legare le funzionalità della pagina in uno dei verbi HTTP (o può costringerti a creare un metodo complesso post che gestisce diversi tipi di lavorazione).
Per gestire qualsiasi funzionalità orientato alle transazioni, è possibile aggiungere una route che specifica un metodo (chiamato una "azione" in routing-parla) sul controller per nome piuttosto che di tipo HTTP. Nell'esempio seguente viene definito un URL che indirizza una richiesta a un metodo denominato assegnaCustomerToOrder ed estrae un IDCliente e OrderID dall'URL (a differenza dei metodi post, metodi associati con altri verbi HTTP possono accettare parametri multipli):
RouteTable.Routes.MapHttpRoute(
"CustomerManagementAssign",
"CustomerManagement/Assign/{CustID}/{OrderID}",
new { Controller = "Customer", Action="AssignCustomerToOrder" },
new { httpMethod = new HttpMethodConstraint("Get") }
);
Questa dichiarazione per il metodo raccoglie i parametri estratti dall'URL:
[HttpGet]
public HttpResponseMessage AssignCustomerToOrder(
string CustID, string OrderID)
{
La funzione intercetta cablata per l'evento lato client appropriato utilizza la funzione get jQuery per passare un URL con i componenti corretti:
function AssignOrder() {
$.get('CustomerManagement/Assign/' +
$("#CustomerID").val() + "/" + "A123",
function (data, status) {
$("#Messages").text(status);
});
return false;
}
Per ricapitolare, il file di codice per una pagina ASPX tradizionale di refactoring in un controller di Web API non è un compito banale. Tuttavia, la flessibilità dell'API Web ASP.NET , il potere fornisce per l'associazione dati HTTP agli oggetti .NET e la capacità di sfruttare gli standard HTTP forniscono un modo potenziale per spostare le applicazioni esistenti a un modello MVC/TDD — e migliorare la scalabilità mediante l'abilitazione di AJAX alla pagina lungo la strada. Dispone inoltre di un paradigma per la creazione di nuove applicazioni ASP.NET che sfruttano la funzionalità dell'API Web ASP.NET e la produttività dei moduli Web.
Peter Vogel è un principale a PH & V Information Services, specializzata in sviluppo ASP.NET con esperienza in architettura service-oriented architecture, XML, database e progettazione dell'interfaccia utente.
Grazie ai seguenti esperti tecnici per la revisione di questo articolo: Christopher Bennage e Daniel Roth
Christopher Bennage è uno sviluppatore di Microsoft sui modelli & Squadra di pratiche. Suo compito è di scoprire, raccogliere e incoraggiare le pratiche che portano gli sviluppatori di gioia. Tra i suoi recenti interessi tecnici sono JavaScript e sviluppo del gioco (casual). Blog di lui a http://dev.bennage.com.
Daniel Roth è un senior program manager del team di Windows Azure Application Platform attualmente lavorando su ASP.NET Web API. Prima di lavorare su ASP.NET ha lavorato su WCF, a partire da quando in primo luogo spedito in .NET Framework 3.0. Le sue passioni includono deliziando i clienti facendo quadri semplice e facile da usare.