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
Paginare i risultati con QuickGrid in Blazor
Hosting di componenti WebAssembly in un'applicazione Blazor static
Creare un'applicazione React e configurare Tailwind CSS
Definire stili a livello di libreria in Angular
Utilizzare EF.Constant per evitare la parametrizzazione di query SQL
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Modificare i metadati nell'head dell'HTML di una Blazor Web App
Code scanning e advanced security con Azure DevOps
Utilizzare i primary constructor di C# per inizializzare le proprietà
Creazione di componenti personalizzati in React.js con Tailwind CSS
Utilizzare Azure AI Studio per testare i modelli AI
Usare un KeyedService di default in ASP.NET Core 8