Con il rilascio ufficiale del .NET Framework 4.6 avvenuto lo scorso luglio, Microsoft introduce alcuni miglioramenti che interessano anche le applicazioni ASP.NET WebForms.
Si tratta di un aggiornamento in-place della precedente versione 4.5.2, che può essere scaricato dai canali ufficiali http://aspit.co/a6g ed installato su sistemi operativi Windows Server 2008 SP2 (o superiore) e, per il desktop, da Windows Vista SP2.
Nel caso in cui non abbiate ancora effettuato l'aggiornamento a Visual Studio 2015, potrete comunque beneficiare di queste nuove funzionalità da Visual Studio 2012 o 2013 scaricando l'apposito Targeting Pack http://aspit.co/a6h ed impostando il .NET Framework 4.6 come framework di destinazione del vostro progetto.
Il miglioramento di cui parleremo oggi è il supporto al model binding asincrono.
Il model binding è una funzionalità nata con ASP.NET MVC, reinterpretata successivamente per ASP.NET WebForms che permette ad un databound control come la GridView di scambiare dati con i nostri metodi di business, anziché con sorgenti come il SqlDataSource.
Marco De Sanctis ne ha già fornito un esempio in un suo precedente script:
http://aspit.co/aju
Con il .NET Framework 4.6, il model binding per ASP.NET WebForms diventa ancor più efficiente perché in grado di sfruttare metodi asincroni per l'ottenimento e l'aggiornamento dei dati, a tutto vantaggio delle prestazioni della nostra applicazione web, soprattutto in condizioni di carico elevato.
Iniziamo aggiungendo l'attributo Async="true" alla direttiva @Page, che ci abiliterà all'uso dei metodi asincroni.
<%@ Page Async="true" %>
Nel markup della WebForm, aggiungiamo una GridView che useremo per visualizzare e gestire gli elementi esistenti. Inoltre, aggiungiamo un DetailsView per inserirne di nuovi.
<!-- GridView per visualizzare, modificare ed eliminare prodotti esistenti --> <h2>Lista prodotti</h2> <asp:GridView ID="ProductsList" ItemType="Model.Product" DataKeyNames="ProductId" runat="server" AutoGenerateColumns="false" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" SelectMethod="ReadProducts" UpdateMethod="UpdateProduct" DeleteMethod="DeleteProduct"> <Columns> <asp:BoundField HeaderText="Id" DataField="ProductId" ReadOnly="true" /> <asp:BoundField HeaderText="Descrizione" DataField="Description" /> <asp:BoundField HeaderText="Prezzo in euro" DataField="PriceInEuro" /> </Columns> </asp:GridView> <!-- DetailsView per creare nuovi prodotti --> <h2>Nuovo prodotto</h2> <asp:DetailsView ItemType="Model.Product" DataKeyNames="ProductId" runat="server" DefaultMode="Insert" AutoGenerateRows="false" AutoGenerateInsertButton="true" InsertMethod="CreateProduct"> <Fields> <asp:BoundField HeaderText="Descrizione" DataField="Description" /> <asp:BoundField HeaderText="Prezzo" DataField="PriceInEuro" /> </Fields> </asp:DetailsView>
Il punto interessante di questo esempio risiede negli attributi SelectMethod, UpdateMethod, DeleteMethod e CreateMethod che abbiamo valorizzato con i nomi di metodi asincroni che andremo a creare nel codefile della pagina.
Apriamo dunque il file .aspx.cs ed aggiungiamo i seguenti metodi, resi asincroni dalla parola chiave async e dal tipo Task restituito.
public async Task<IEnumerable<Product>> ReadProducts() { using (var context = new MyOnlineStoreContext()) { // Estraggo l'elenco dei prodotti in maniera asincrona return await context.Products.ToListAsync(); } } public async Task UpdateProduct(Product product) { if (!ModelState.IsValid) return; using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Modified; // Aggiorno il prodotto in maniera asincrona await context.SaveChangesAsync(); } } public async Task DeleteProduct(Product product) { using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Deleted; // Elimino il prodotto in maniera asincrona await context.SaveChangesAsync(); } } public async Task CreateProduct(Product product) { if (!ModelState.IsValid) return; using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Added; // Aggiungo il prodotto in maniera asincrona await context.SaveChangesAsync(); } //Indico alla GridView che deve riottenere l'elenco dei prodotti ProductsList.DataBind(); }
In questo modo, possiamo sfruttare appieno le tecnologie che, a loro volta, espongono API asincrone come Entity Framework 6. Nell'esempio mostrato, la parola chiave await, che viene usata con i metodi ToListAsync e SaveChangesAsync, permette ad IIS di riutilizzare in maniera intelligente i thread di elaborazione delle richieste web, così che non restino bloccati e inutilizzati in attesa che la lettura o la scrittura al database si completi.
Il model binding asincrono diventa ancor più consigliato quando consumiamo risorse soggette ad una latenza di rete consistente, come ad esempio web services o altro tipo di servizi che siano ospitati su macchine remote o nel cloud.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Implementare l'infinite scroll con QuickGrid in Blazor Server
Utilizzare l nesting nativo dei CSS
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Creare una libreria CSS universale: Clip-path
Gestione degli stili CSS con le regole @layer
Utilizzare WhenEach per processare i risultati di una lista di task
Estrarre dati randomici da una lista di oggetti in C#
Testare l'invio dei messaggi con Event Hubs Data Explorer
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Ordine e importanza per @layer in CSS