Novità di Web Forms in ASP.NET 4.5
La nuova versione di Web Forms ASP.NET introduce numerosi miglioramenti incentrati sul miglioramento dell'esperienza utente durante l'uso dei dati.
Nelle versioni precedenti di Web Form, quando si usa il data binding per generare il valore di un membro dell'oggetto, sono state usate le espressioni di data binding Bind() o Eval(). Nella nuova versione di ASP.NET è possibile dichiarare il tipo di dati a cui verrà associato un controllo usando una nuova proprietà ItemType. L'impostazione di questa proprietà consentirà di usare una variabile fortemente tipizzata per ottenere i vantaggi completi dell'esperienza di sviluppo di Visual Studio, ad esempio IntelliSense, spostamento dei membri e controllo in fase di compilazione.
Con i controlli associati a dati, è ora anche possibile specificare metodi personalizzati per la selezione, l'aggiornamento, l'eliminazione e l'inserimento di dati, semplificando l'interazione tra i controlli pagina e la logica dell'applicazione. Sono state inoltre aggiunte funzionalità di associazione di modelli a ASP.NET, il che significa che è possibile eseguire il mapping dei dati dalla pagina direttamente ai parametri del tipo di metodo.
Anche la convalida dell'input utente deve essere più semplice con la versione più recente di Web Form. È ora possibile annotare le classi del modello con attributi di convalida dallo spazio dei nomi System.ComponentModel.DataAnnotations e richiedere che tutti i controlli del sito convalidano l'input dell'utente usando tali informazioni. La convalida lato client in Web Form è ora integrata con jQuery, fornendo codice lato client più pulito e funzionalità JavaScript non invadenti.
Nell'area di convalida delle richieste sono stati apportati miglioramenti per semplificare la disattivazione selettiva della convalida delle richieste per parti specifiche delle applicazioni o leggere i dati delle richieste invalidati.
Sono stati apportati alcuni miglioramenti ai controlli server Web Form per sfruttare le nuove funzionalità di HTML5:
- La proprietà TextMode del controllo TextBox è stata aggiornata per supportare i nuovi tipi di input HTML5, ad esempio posta elettronica, datetime e così via.
- Il controllo FileUpload supporta ora più caricamenti di file dai browser che supportano questa funzionalità HTML5.
- I controlli validator supportano ora la convalida degli elementi di input HTML5.
- I nuovi elementi HTML5 con attributi che rappresentano un URL ora supportano runat="server". Di conseguenza, è possibile usare ASP.NET convenzioni nei percorsi URL, ad esempio l'operatore ~ per rappresentare la radice dell'applicazione (ad esempio, <video runat="server" src="~/myVideo.wmv"></video>).
- Il controllo UpdatePanel è stato corretto per supportare la registrazione di campi di input HTML5.
Nel portale ASP.NET ufficiale sono disponibili altri esempi delle nuove funzionalità in ASP.NET WebForms 4.5: Novità di ASP.NET 4.5 e Visual Studio 2012
Tutti i frammenti e il codice di esempio sono inclusi in Web Camp Training Kit.
Obiettivi
In questo lab pratico si apprenderà come:
- Usare espressioni di data binding fortemente tipizzato
- Usare nuove funzionalità di associazione di modelli in Web Form
- Usare provider di valori per il mapping dei dati della pagina ai metodi code-behind
- Usare annotazioni dati per la convalida dell'input utente
- Sfruttare i vantaggi della convalida lato client non invadente con jQuery in Web Form
- Implementare la convalida granulare delle richieste
- Implementare l'elaborazione asincrona delle pagine in Web Form
Prerequisiti
Per completare questo lab, è necessario disporre degli elementi seguenti:
- Microsoft Visual Studio Express 2012 per Web o superiore (vedere Appendice A per istruzioni su come installarlo).
Attrezzaggio
Installazione di frammenti di codice
Per praticità, gran parte del codice che si gestirà con questo lab è disponibile come frammenti di codice di Visual Studio. Per installare i frammenti di codice, eseguire il file .\Source\Setup\CodeSnippets.vsi .
Se non si ha familiarità con i frammenti di codice di Visual Studio e si vuole imparare a usarli, è possibile fare riferimento all'appendice di questo documento "Appendice C: Uso di frammenti di codice".
Esercizi
Questo lab pratico include gli esercizi seguenti:
- Esercizio 1: Associazione di modelli in Web Forms ASP.NET
- Esercizio 2: Convalida dei dati
- Esercizio 3: Elaborazione asincrona delle pagine in Web Forms ASP.NET
Nota
Ogni esercizio è accompagnato da una cartella End contenente la soluzione risultante da ottenere dopo aver completato gli esercizi. È possibile usare questa soluzione come guida se sono necessarie altre informazioni sull'utilizzo degli esercizi.
Tempo stimato per il completamento del lab: 60 minuti.
Esercizio 1: Associazione di modelli in Web Forms ASP.NET
La nuova versione di Web Forms ASP.NET introduce una serie di miglioramenti incentrati sul miglioramento dell'esperienza quando si usano i dati. In questo esercizio verranno fornite informazioni sui controlli dati fortemente tipizzato e sull'associazione di modelli.
Attività 1 - Uso di data binding fortemente tipizzato
In questa attività verranno individuati i nuovi binding fortemente tipizzato disponibili in ASP.NET 4.5.
Aprire la soluzione Begin disponibile nella cartella Source/Ex1-ModelBinding/Begin/ .
È necessario scaricare alcuni pacchetti NuGet mancanti prima di continuare. A tale scopo, fare clic sul menu Progetto e selezionare Gestisci pacchetti NuGet.
Nella finestra di dialogo Gestisci pacchetti NuGet fare clic su Ripristina per scaricare i pacchetti mancanti.
Compilare infine la soluzione facendo clic su Compila | soluzione.
Nota
Uno dei vantaggi dell'uso di NuGet è che non è necessario spedire tutte le librerie nel progetto, riducendo le dimensioni del progetto. Con NuGet Power Tools, specificando le versioni del pacchetto nel file Packages.config, sarà possibile scaricare tutte le librerie necessarie la prima volta che si esegue il progetto. Questo è il motivo per cui è necessario eseguire questi passaggi dopo aver aperto una soluzione esistente da questo lab.
Aprire la pagina Customers.aspx . Inserire un elenco non numerato nel controllo principale e includere un controllo repeater all'interno per elencare ogni cliente. Impostare il nome del ripetitore su customersRepeater , come illustrato nel codice seguente.
Nelle versioni precedenti di Web Form, quando si usa il data binding per generare il valore di un membro in un oggetto a cui si esegue il data binding, si userebbe un'espressione di data binding, insieme a una chiamata al metodo Eval, passando il nome del membro come stringa.
In fase di esecuzione, queste chiamate a Eval useranno la reflection sull'oggetto attualmente associato per leggere il valore del membro con il nome specificato e visualizzare il risultato nel codice HTML. Questo approccio semplifica l'associazione dei dati a dati arbitrari e non con forme.
Sfortunatamente, molte delle grandi funzionalità in fase di sviluppo in Visual Studio, tra cui IntelliSense per i nomi dei membri, il supporto per la navigazione (ad esempio Vai a definizione) e il controllo in fase di compilazione.
... <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <h3>Customers</h3> <ul> <asp:Repeater ID="customersRepeater" runat="server"> <ItemTemplate> <li> <%# Eval("FirstName") %> <%# Eval("LastName") %> </li> </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>
Aprire il file Customers.aspx.cs .
Aggiungere l'istruzione using seguente.
using System.Linq;
Nel metodo Page_Load aggiungere codice per popolare il ripetitore con l'elenco dei clienti.
(Frammento di codice - Lab Web Forms - Ex01 - Associare l'origine dati dei clienti
protected void Page_Load(object sender, EventArgs e) { using (var db = new WebFormsLab.Model.ProductsContext()) { this.customersRepeater.DataSource = db.Customers.ToList(); this.customersRepeater.DataBind(); } }
La soluzione usa EntityFramework insieme a CodeFirst per creare e accedere al database. Nel codice seguente, customersRepeater è associato a una query materializzata che restituisce tutti i clienti dal database.
Premere F5 per eseguire la soluzione e passare alla pagina Clienti per visualizzare il ripetitore in azione. Poiché la soluzione usa CodeFirst, il database verrà creato e popolato nell'istanza di SQL Express locale durante l'esecuzione dell'applicazione.
Presentazione dei clienti con un ripetitore
Nota
In Visual Studio 2012 IIS Express è il server di sviluppo Web predefinito.
Chiudere il browser e tornare a Visual Studio.
Sostituire ora l'implementazione per usare associazioni fortemente tipate. Aprire la pagina Customers.aspx e usare il nuovo attributo ItemType nel ripetitore per impostare il tipo Di cliente come tipo di associazione.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <ul> <asp:Repeater ID="customersRepeater" ItemType="WebFormsLab.Model.Customer" runat="server"> <ItemTemplate> ... </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>
La proprietà ItemType consente di dichiarare il tipo di dati a cui verrà associato il controllo e di utilizzare un'associazione fortemente tipizzata all'interno del controllo associato a dati.
Sostituire il contenuto ItemTemplate con il codice seguente.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> ... <ul> <asp:Repeater ID="customersRepeater" ItemType="WebFormsLab.Model.Customer" runat="server"> <ItemTemplate> <li> <a href="CustomerDetails.aspx?id=<%#: Item.Id %>"> <%#: Item.FirstName %> <%#: Item.LastName %> </a> </li> </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>
Uno svantaggio degli approcci precedenti è che le chiamate a Eval() e Bind() sono associate in ritardo, ovvero si passano stringhe per rappresentare i nomi delle proprietà. Ciò significa che non si ottiene IntelliSense per i nomi dei membri, il supporto per lo spostamento del codice (ad esempio Vai a definizione) né il supporto per il controllo in fase di compilazione.
L'impostazione della proprietà ItemType determina la generazione di due nuove variabili tipate nell'ambito delle espressioni di data binding: Item e BindItem. È possibile usare queste variabili fortemente tipate nelle espressioni di data binding e ottenere i vantaggi completi dell'esperienza di sviluppo di Visual Studio.
": " usato nell'espressione codifica automaticamente l'output per evitare problemi di sicurezza ( ad esempio attacchi di scripting intersito). Questa notazione è disponibile a partire da .NET 4 per la scrittura delle risposte, ma ora è disponibile anche nelle espressioni di data binding.
Nota
Il membro Item funziona per l'associazione unidirezionale. Se si desidera eseguire l'associazione bidirezionale, usare il membro BindItem .
Supporto di IntelliSense nell'associazione fortemente tipizzata
Premere F5 per eseguire la soluzione e passare alla pagina Clienti per assicurarsi che le modifiche funzionino come previsto.
Presentazione dei dettagli del cliente
Chiudere il browser e tornare a Visual Studio.
Attività 2 - Introduzione all'associazione di modelli in Web Form
Nelle versioni precedenti di Web Forms ASP.NET, quando si vuole eseguire il data binding bidirezionale, sia il recupero che l'aggiornamento dei dati, è necessario usare un oggetto Origine dati. Potrebbe trattarsi di un'origine dati oggetto, di un'origine dati SQL, di un'origine dati LINQ e così via. Tuttavia, se lo scenario richiede codice personalizzato per la gestione dei dati, è necessario usare l'origine dati oggetto e questo ha portato alcuni svantaggi. Ad esempio, è necessario evitare tipi complessi ed è necessario gestire le eccezioni durante l'esecuzione della logica di convalida.
Nella nuova versione di Web Forms ASP.NET i controlli associati a dati supportano l'associazione di modelli. Ciò significa che è possibile specificare metodi di selezione, aggiornamento, inserimento ed eliminazione direttamente nel controllo associato a dati per chiamare la logica dal file code-behind o da un'altra classe.
Per altre informazioni, si userà un controllo GridView per elencare le categorie di prodotti usando il nuovo attributo SelectMethod . Questo attributo consente di specificare un metodo per il recupero dei dati GridView.
Aprire la pagina Products.aspx e includere un controllo GridView. Configurare GridView come illustrato di seguito per usare associazioni fortemente tipate e abilitare l'ordinamento e il paging.
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryID"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" SortExpression="CategoryId" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" SortExpression="CategoryName" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </asp:Content>
Usare il nuovo attributo SelectMethod per configurare GridView per chiamare un metodo GetCategories per selezionare i dati.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" SortExpression="CategoryId" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" SortExpression="CategoryName" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
Aprire il file code-behind Products.aspx.cs e aggiungere le istruzioni using seguenti.
(Frammento di codice - Lab Web Forms - Ex01 - Spazi dei nomi)
using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using WebFormsLab.Model;
Aggiungere un membro privato nella classe Products e assegnare una nuova istanza di ProductsContext. Questa proprietà archivierà il contesto dei dati di Entity Framework che consente di connettersi al database.
public partial class Products : System.Web.UI.Page { private ProductsContext db = new ProductsContext(); ...
Creare un metodo GetCategories per recuperare l'elenco di categorie usando LINQ. La query includerà la proprietà Products in modo che GridView possa visualizzare la quantità di prodotti per ogni categoria. Si noti che il metodo restituisce un oggetto IQueryable non elaborato che rappresenta la query da eseguire in un secondo momento nel ciclo di vita della pagina.
(Frammento di codice - Lab Web Forms - Ex01 - GetCategories)
public IQueryable<Category> GetCategories() { var query = this.db.Categories .Include(c => c.Products); return query; }
Nota
Nelle versioni precedenti di Web Forms ASP.NET, abilitando l'ordinamento e il paging usando la logica del repository all'interno di un contesto origine dati oggetto, è necessario scrivere codice personalizzato e ricevere tutti i parametri necessari. Ora, poiché i metodi di data binding possono restituire IQueryable e rappresenta una query ancora da eseguire, ASP.NET può occuparsi della modifica della query per aggiungere i parametri di ordinamento e paging appropriati.
Premere F5 per avviare il debug del sito e passare alla pagina Prodotti. Si noterà che GridView viene popolato con le categorie restituite dal metodo GetCategories.
Popolamento di un controllo GridView tramite l'associazione di modelli
Premere MAIUSC+F5 Arresta debug.
Attività 3 - Provider di valori nell'associazione di modelli
L'associazione di modelli non solo consente di specificare metodi personalizzati per lavorare con i dati direttamente nel controllo associato a dati, ma consente anche di eseguire il mapping dei dati dalla pagina ai parametri di questi metodi. Nel parametro del metodo è possibile usare gli attributi del provider di valori per specificare l'origine dati del valore. Ad esempio:
- Controlli nella pagina
- Valori di stringa di query
- Visualizzare i dati
- Stato della sessione
- Cookie
- Dati del modulo pubblicati
- Visualizzare lo stato
- Sono supportati anche provider di valori personalizzati
Se è stato usato ASP.NET MVC 4, si noterà che il supporto dell'associazione di modelli è simile. Infatti, queste funzionalità sono state ricavate da ASP.NET MVC e spostate nell'assembly System.Web per poterle usare anche in Web Form.
In questa attività si aggiornerà GridView per filtrare i risultati in base alla quantità di prodotti per ogni categoria, ricevendo il parametro di filtro con l'associazione di modelli.
Tornare alla pagina Products.aspx .
Nella parte superiore di GridView aggiungere un'etichetta e un controllo ComboBox per selezionare il numero di prodotti per ogni categoria, come illustrato di seguito.
<h3>Categories</h3> <asp:Label ID="Label1" runat="server" AssociatedControlID="minProductsCount"> Show categories with at least this number of products: </asp:Label> <asp:DropDownList runat="server" ID="minProductsCount" AutoPostBack="true"> <asp:ListItem Value="" Text="-" /> <asp:ListItem Text="1" /> <asp:ListItem Text="3" /> <asp:ListItem Text="5" /> </asp:DropDownList> <br/>
Aggiungere un oggetto EmptyDataTemplate a GridView per visualizzare un messaggio quando non sono presenti categorie con il numero selezionato di prodotti.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> <EmptyDataTemplate> No categories found with a product count of <%#: minProductsCount.SelectedValue %> </EmptyDataTemplate> </asp:GridView>
Aprire il code-behind Products.aspx.cs e aggiungere l'istruzione using seguente.
using System.Web.ModelBinding;
Modificare il metodo GetCategories per ricevere un argomento minProductsCount integer e filtrare i risultati restituiti. A tale scopo, sostituire il metodo con il codice seguente.
(Frammento di codice - Lab Web Forms - Ex01 - GetCategories 2)
public IQueryable<Category> GetCategories([Control]int? minProductsCount) { var query = this.db.Categories .Include(c => c.Products); if (minProductsCount.HasValue) { query = query.Where(c => c.Products.Count >= minProductsCount); } return query; }
Il nuovo attributo [Control] nell'argomento minProductsCount consentirà di ASP.NET conoscere il relativo valore deve essere popolato usando un controllo nella pagina. ASP.NET cercherà qualsiasi controllo corrispondente al nome dell'argomento (minProductsCount) ed eseguirà il mapping e la conversione necessari per riempire il parametro con il valore del controllo.
In alternativa, l'attributo fornisce un costruttore di overload che consente di specificare il controllo da dove ottenere il valore.
Nota
Uno degli obiettivi delle funzionalità di data binding è ridurre la quantità di codice che deve essere scritto per l'interazione tra le pagine. Oltre al provider di valori [Control], è possibile usare altri provider di associazione di modelli nei parametri del metodo. Alcune di esse sono elencate nell'introduzione all'attività.
Premere F5 per avviare il debug del sito e passare alla pagina Prodotti. Selezionare un certo numero di prodotti nell'elenco a discesa e notare come GridView viene aggiornato.
Filtro di GridView con un valore elenco a discesa
Terminare il debug
Attività 4 - Uso dell'associazione di modelli per il filtro
In questa attività si aggiungerà un secondo elemento Figlio GridView per visualizzare i prodotti all'interno della categoria selezionata.
Aprire la pagina Products.aspx e aggiornare le categorie GridView per generare automaticamente il pulsante Seleziona.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true">
Aggiungere un secondo controllo GridView denominato productsGrid nella parte inferiore. Impostare ItemType su WebFormsLab.Model.Product, DataKeyNames su ProductId e SelectMethod su GetProducts. Impostare AutoGenerateColumns su false e aggiungere le colonne per ProductId, ProductName, Description e UnitPrice.
<h3>Products</h3> <asp:GridView ID="productsGrid" runat="server" CellPadding="4" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Product" DataKeyNames="ProductId" SelectMethod="GetProducts"> <Columns> <asp:BoundField DataField="ProductId" HeaderText="ID" /> <asp:BoundField DataField="ProductName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" HtmlEncode="false" /> <asp:BoundField DataField="UnitPrice" HeaderText="Price" /> </Columns> <EmptyDataTemplate> Select a category above to see its products </EmptyDataTemplate> </asp:GridView>
Aprire il file code-behind Products.aspx.cs . Implementare il metodo GetProducts per ricevere l'ID categoria dalla categoria GridView e filtrare i prodotti. L'associazione di modelli imposta il valore del parametro usando la riga selezionata nelle categorieGrid. Poiché il nome dell'argomento e il nome del controllo non corrispondono, è necessario specificare il nome del controllo nel provider di valori di controllo.
(Frammento di codice - Lab Web Forms - Ex01 - GetProducts)
public IEnumerable<Product> GetProducts([Control("categoriesGrid")]int? categoryId) { return this.db.Products.Where(p => p.CategoryId == categoryId); }
Nota
Questo approccio semplifica lo unit test di questi metodi. In un contesto di unit test, in cui Web Form non è in esecuzione, l'attributo [Control] non eseguirà alcuna azione specifica.
Aprire la pagina Products.aspx e individuare i prodotti GridView. Aggiornare i prodotti GridView per visualizzare un collegamento per la modifica del prodotto selezionato.
<h3>Products</h3> <asp:GridView ID="productsGrid" runat="server" CellPadding="4" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Product" DataKeyNames="ProductId" SelectMethod="GetProducts"> <Columns> <asp:TemplateField> <ItemTemplate> <a href="ProductDetails.aspx?productId=<%#: Item.ProductId %>">View</a> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="ProductId" HeaderText="ID" /> <asp:BoundField DataField="ProductName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" HtmlEncode="false" /> <asp:BoundField DataField="UnitPrice" HeaderText="Price" /> </Columns> <EmptyDataTemplate> Select a category above to see its products </EmptyDataTemplate> </asp:GridView>
Aprire il code-behind della pagina ProductDetails.aspx e sostituire il metodo SelectProduct con il codice seguente.
(Frammento di codice - Lab Web Forms - Ex01 - Metodo SelectProduct)
public Product SelectProduct([QueryString]int? productId) { return this.db.Products.Find(productId); }
Nota
Si noti che l'attributo [QueryString] viene usato per riempire il parametro del metodo da un parametro productId nella stringa di query.
Premere F5 per avviare il debug del sito e passare alla pagina Prodotti. Selezionare qualsiasi categoria nelle categorie GridView e notare che i prodotti GridView vengono aggiornati.
Visualizzazione dei prodotti dalla categoria selezionata
Fare clic sul collegamento Visualizza su un prodotto per aprire la pagina ProductDetails.aspx.
Si noti che la pagina sta recuperando il prodotto con SelectMethod usando il parametro productId dalla stringa di query.
Visualizzazione dei dettagli del prodotto
Nota
La possibilità di digitare una descrizione HTML verrà implementata nell'esercizio successivo.
Attività 5 - Uso dell'associazione di modelli per le operazioni di aggiornamento
Nell'attività precedente è stata usata l'associazione di modelli principalmente per la selezione dei dati, in questa attività si apprenderà come usare l'associazione di modelli nelle operazioni di aggiornamento.
Le categorie GridView verranno aggiornate per consentire agli utenti di aggiornare le categorie.
Aprire la pagina Products.aspx e aggiornare le categorie GridView per generare automaticamente il pulsante Modifica e usare il nuovo attributo UpdateMethod per specificare un metodo UpdateCategory per aggiornare l'elemento selezionato.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true" AutoGenerateEditButton="true" UpdateMethod="UpdateCategory">
L'attributo DataKeyNames in GridView definisce quali sono i membri che identificano in modo univoco l'oggetto associato al modello e pertanto, quali sono i parametri che il metodo update deve almeno ricevere.
Aprire il file code-behind Products.aspx.cs e implementare il metodo UpdateCategory . Il metodo deve ricevere l'ID categoria per caricare la categoria corrente, popolare i valori da GridView e quindi aggiornare la categoria.
(Frammento di codice - Lab Web Form - Ex01 - UpdateCategory)
public void UpdateCategory(int categoryId) { var category = this.db.Categories.Find(categoryId); this.TryUpdateModel(category); if (this.ModelState.IsValid) { this.db.SaveChanges(); } }
Il nuovo metodo TryUpdateModel nella classe Page è responsabile del popolamento dell'oggetto modello usando i valori dei controlli nella pagina. In questo caso, sostituirà i valori aggiornati della riga GridView corrente da modificare nell'oggetto categoria .
Nota
L'esercizio successivo illustra l'utilizzo di ModelState.IsValid per la convalida dei dati immessi dall'utente durante la modifica dell'oggetto.
Eseguire il sito e passare alla pagina Prodotti. Modificare una categoria. Digitare un nuovo nome e quindi fare clic su Aggiorna per rendere persistenti le modifiche.
Modifica delle categorie
Esercizio 2: Convalida dei dati
In questo esercizio verranno fornite informazioni sulle nuove funzionalità di convalida dei dati in ASP.NET 4.5. Verranno estratte le nuove funzionalità di convalida non invadenti in Web Form. Si useranno annotazioni di dati nelle classi del modello di applicazione per la convalida dell'input utente e infine si apprenderà come attivare o disattivare la convalida delle richieste ai singoli controlli in una pagina.
Attività 1 - Convalida non invasiva
I moduli con dati complessi, inclusi i validator, tendono a generare un numero eccessivo di codice JavaScript nella pagina, che può rappresentare circa il 60% del codice. Con la convalida non invadente abilitata, il codice HTML sarà più pulito e ordinato.
In questa sezione si abiliterà la convalida non invasiva in ASP.NET per confrontare il codice HTML generato da entrambe le configurazioni.
Aprire Visual Studio 2012 e aprire la soluzione Begin che si trova nella cartella Source\Ex2-Validation\Begin di questo lab. In alternativa, è possibile continuare a lavorare sulla soluzione esistente dell'esercizio precedente.
Se è stata aperta la soluzione Begin fornita, è necessario scaricare alcuni pacchetti NuGet mancanti prima di continuare. A tale scopo, nel Esplora soluzioni fare clic sul progetto WebFormsLab Gestisci pacchetti NuGet.
Nella finestra di dialogo Gestisci pacchetti NuGet fare clic su Ripristina per scaricare i pacchetti mancanti.
Compilare infine la soluzione facendo clic su Compila | soluzione.
Nota
Uno dei vantaggi dell'uso di NuGet è che non è necessario spedire tutte le librerie nel progetto, riducendo le dimensioni del progetto. Con NuGet Power Tools, specificando le versioni del pacchetto nel file Packages.config, sarà possibile scaricare tutte le librerie necessarie la prima volta che si esegue il progetto. Questo è il motivo per cui è necessario eseguire questi passaggi dopo aver aperto una soluzione esistente da questo lab.
Premere F5 per avviare l'applicazione Web. Passare alla pagina Clienti e fare clic sul collegamento Aggiungi un nuovo cliente .
Fare clic con il pulsante destro del mouse sulla pagina del browser e scegliere Visualizza origine per aprire il codice HTML generato dall'applicazione.
Visualizzazione del codice HTML della pagina
Scorrere il codice sorgente della pagina e notare che ASP.NET ha inserito codice JavaScript e validator di dati nella pagina per eseguire le convalide e visualizzare l'elenco degli errori.
Codice JavaScript di convalida nella pagina CustomerDetails
Chiudere il browser e tornare a Visual Studio.
A questo momento si abiliterà la convalida non invasiva. Aprire Web.Config e individuare ValidationSettings:UnobtrusiveValidationMode nella sezione AppSettings . Impostare il valore della chiave su WebForms.
<configuration> ... <appSettings> <add key="aspnet:uselegacysynchronizationcontext" value="false" /> <add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"/>
Nota
È anche possibile impostare questa proprietà nell'evento "Page_Load" nel caso in cui si voglia abilitare la convalida unobtrusive solo per alcune pagine.
Aprire CustomerDetails.aspx e premere F5 per avviare l'applicazione Web.
Premere il tasto F12 per aprire gli strumenti di sviluppo di Internet Explorer. Dopo aver aperto gli strumenti di sviluppo, selezionare la scheda script. Selezionare CustomerDetails.aspx dal menu e prendere nota che gli script necessari per eseguire jQuery nella pagina sono stati caricati nel browser dal sito locale.
Caricamento dei file JavaScript jQuery direttamente dal server IIS locale
Chiudere il browser per tornare a Visual Studio. Aprire di nuovo il file Site.Master e individuare ScriptManager. Aggiungere la proprietà EnableCdn dell'attributo con il valore True. In questo modo jQuery verrà caricato dall'URL online, non dall'URL del sito locale.
Aprire CustomerDetails.aspx in Visual Studio. Premere il tasto F5 per eseguire il sito. Una volta aperto Internet Explorer, premere il tasto F12 per aprire gli strumenti di sviluppo. Selezionare la scheda Script e quindi esaminare l'elenco a discesa. Si noti che i file JavaScript jQuery non vengono più caricati dal sito locale, ma piuttosto dalla rete CDN jQuery online.
Caricamento dei file JavaScript jQuery dalla rete CDN
Aprire di nuovo il codice sorgente della pagina HTML usando l'opzione Visualizza origine nel browser. Si noti che abilitando la convalida non invasiva ASP.NET è stato sostituito il codice JavaScript inserito con gli attributi data- *.
Codice di convalida non invadente
Nota
In questo esempio è stato illustrato come un riepilogo di convalida con annotazioni di dati sia stato semplificato in poche righe HTML e JavaScript. In precedenza, senza convalida non invadente, maggiore sarà il numero di controlli di convalida aggiunti, maggiore sarà il codice di convalida JavaScript.
Attività 2 - Convalida del modello con annotazioni di dati
ASP.NET 4.5 introduce la convalida delle annotazioni dei dati per Web Form. Anziché disporre di un controllo di convalida per ogni input, è ora possibile definire vincoli nelle classi del modello e usarli in tutte le applicazioni Web. In questa sezione si apprenderà come usare le annotazioni dei dati per la convalida di un modulo del cliente nuovo/modificato.
Aprire CustomerDetail.aspx pagina. Si noti che il nome del cliente e il secondo nome nelle sezioni EditItemTemplate e InsertItemTemplate vengono convalidati usando i controlli RequiredFieldValidator. Ogni validator è associato a una determinata condizione, pertanto è necessario includere tutti i validator come condizioni da controllare.
Aggiungere annotazioni di dati per convalidare la classe del modello Customer. Aprire Customer.cs classe nella cartella Model e decorare ogni proprietà usando gli attributi di annotazione dei dati.
(Frammento di codice - Lab Web Forms - Ex02 - Annotazioni dei dati)
namespace WebFormsLab.Model { using System.Collections.Generic; using System.ComponentModel.DataAnnotations; public class Customer { [Key] public int Id { get; set; } [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } [Range(0, 130)] public int Age { get; set; } public Address Address { get; set; } [Phone] public string DaytimePhone { get; set; } [EmailAddress, StringLength(256)] public string EmailAddress { get; set; } } }
Nota
.NET Framework 4.5 ha esteso la raccolta di annotazioni dati esistente. Queste sono alcune delle annotazioni dati che è possibile usare: [CreditCard], [Phone], [EmailAddress], [Range], [Compare], [Url], [FileExtensions], [Required], [Key], [RegularExpression].
Alcuni esempi di utilizzo:
[Chiave]: specifica che un attributo è l'identificatore univoco
[Range(0.4, 0.5, ErrorMessage="{Write an error message}"]: Double range
[EmailAddress(ErrorMessage="Posta elettronica non valida"), MaxLength(56)]: due annotazioni nella stessa riga.
È anche possibile definire messaggi di errore personalizzati all'interno di ogni attributo.
Aprire CustomerDetails.aspx e rimuovere tutti i campi RequiredFieldValidator per i campi nome e cognome nelle sezioni EditItemTemplate e InsertItemTemplate del controllo FormView.
<EditItemTemplate> <fieldset> <p><asp:Label runat="server" AssociatedControlID="firstName">First Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="firstName" Text='<%#: BindItem.FirstName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="firstName" ErrorMessage="Please enter a value for First Name" ForeColor="Red" /> </p> <p><asp:Label runat="server" AssociatedControlID="lastName">Last Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="lastName" Text='<%#: BindItem.LastName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="lastName" ErrorMessage="Please enter a value for Last Name" ForeColor="Red" /> </p> ... <InsertItemTemplate> <fieldset> <p><asp:Label runat="server" AssociatedControlID="firstName">First Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="firstName" Text='<%#: BindItem.FirstName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="firstName" ErrorMessage="Please enter a value for First Name" ForeColor="Red" /> </p> <p><asp:Label runat="server" AssociatedControlID="lastName">Last Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="lastName" Text='<%#: BindItem.LastName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="lastName" ErrorMessage="Please enter a value for Last Name" ForeColor="Red" /> </p> ...
Nota
Un vantaggio dell'uso delle annotazioni dei dati è che la logica di convalida non viene duplicata nelle pagine dell'applicazione. È possibile definirlo una volta nel modello e usarlo in tutte le pagine dell'applicazione che modificano i dati.
Aprire CustomerDetails.aspx code-behind e individuare il metodo SaveCustomer. Questo metodo viene chiamato quando si inserisce un nuovo cliente e riceve il parametro Customer dai valori del controllo FormView. Quando si verifica il mapping tra i controlli pagina e l'oggetto parametro, ASP.NET eseguirà la convalida del modello su tutti gli attributi di annotazione dei dati e riempie il dizionario ModelState con gli errori rilevati, se presenti.
ModelState.IsValid restituirà true solo se tutti i campi del modello sono validi dopo l'esecuzione della convalida.
public void SaveCustomer(Customer customer) { if (this.ModelState.IsValid) { using (var db = new ProductsContext()) { ...
Aggiungere un controllo ValidationSummary alla fine della pagina CustomerDetails per visualizzare l'elenco di errori del modello.
</fieldset> </InsertItemTemplate> </asp:FormView> <asp:ValidationSummary runat="server" ShowModelStateErrors="true" ForeColor="Red" HeaderText="Please check the following errors:"/> </asp:Content>
ShowModelStateErrors è una nuova proprietà nel controllo ValidationSummary che, se impostato su true, il controllo mostrerà gli errori del dizionario ModelState. Questi errori provengono dalla convalida delle annotazioni dei dati.
Premere F5 per eseguire l'applicazione Web. Completare il modulo con alcuni valori errati e fare clic su Salva per eseguire la convalida. Si noti il riepilogo degli errori nella parte inferiore.
Convalida con annotazioni dei dati
Attività 3 - Gestione degli errori del database personalizzati con ModelState
Nella versione precedente di Web Form la gestione degli errori del database, ad esempio una stringa troppo lunga o una violazione di chiave univoca, potrebbe comportare la generazione di eccezioni nel codice del repository e la gestione delle eccezioni nel code-behind per visualizzare un errore. È necessaria una grande quantità di codice per eseguire operazioni relativamente semplici.
In Web Form 4.5, l'oggetto ModelState può essere usato per visualizzare gli errori nella pagina, dal modello o dal database, in modo coerente.
In questa attività si aggiungerà il codice per gestire correttamente le eccezioni del database e verrà visualizzato il messaggio appropriato all'utente usando l'oggetto ModelState.
Mentre l'applicazione è ancora in esecuzione, provare ad aggiornare il nome di una categoria usando un valore duplicato.
Aggiornamento di una categoria con un nome duplicato
Si noti che viene generata un'eccezione a causa del vincolo "unique" della colonna CategoryName .
Eccezione per i nomi di categoria duplicati
Terminare il debug Nel file code-behind Products.aspx.cs aggiornare il metodo UpdateCategory per gestire le eccezioni generate dal database. Chiamata al metodo SaveChanges() e aggiunta di un errore all'oggetto ModelState.
Il nuovo metodo TryUpdateModel aggiorna l'oggetto categoria recuperato dal database usando i dati del modulo forniti dall'utente.
(Frammento di codice - Lab Web Form - Ex02 - Errori di gestione updateCategory)
public void UpdateCategory(int categoryId) { var category = this.db.Categories.Find(categoryId); this.TryUpdateModel(category); if (this.ModelState.IsValid) { try { this.db.SaveChanges(); } catch (DbUpdateException) { var message = string.Format("A category with the name {0} already exists.", category.CategoryName); this.ModelState.AddModelError("CategoryName", message); } } }
Nota
Idealmente, è necessario identificare la causa dell'eccezione DbUpdateException e verificare se la causa radice è la violazione di un vincolo di chiave univoca.
Aprire Products.aspx e aggiungere un controllo ValidationSummary sotto le categorie GridView per visualizzare l'elenco degli errori del modello.
<asp:GridView ID="categoriesGrid" runat="server" ... </asp:GridView> <asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowModelStateErrors="true" /> <h3>Products</h3>
Eseguire il sito e passare alla pagina Prodotti. Provare ad aggiornare il nome di una categoria usando un valore duplicato.
Si noti che l'eccezione è stata gestita e il messaggio di errore viene visualizzato nel controllo ValidationSummary .
Errore di categoria duplicato
Attività 4 - Richiedere la convalida in Web Forms ASP.NET 4.5
La funzionalità di convalida delle richieste in ASP.NET fornisce un determinato livello di protezione predefinita da attacchi XSS (Cross-Site Scripting). Nelle versioni precedenti di ASP.NET, la convalida delle richieste è stata abilitata per impostazione predefinita e potrebbe essere disabilitata solo per un'intera pagina. Con la nuova versione di Web Forms ASP.NET è ora possibile disabilitare la convalida della richiesta per un singolo controllo, eseguire la convalida della richiesta differita o accedere ai dati delle richieste non convalidati (prestare attenzione se lo si esegue!).
Premere CTRL+F5 per avviare il sito senza eseguire il debug e passare alla pagina Prodotti. Selezionare una categoria e quindi fare clic sul collegamento Modifica su uno dei prodotti.
Digitare una descrizione contenente contenuto potenzialmente pericoloso, ad esempio includendo tag HTML. Prendere nota dell'eccezione generata a causa della convalida della richiesta.
Modifica di un prodotto con contenuto potenzialmente pericoloso
Eccezione generata a causa della convalida della richiesta
Chiudere la pagina e, in Visual Studio, premere MAIUSC+F5 per arrestare il debug.
Aprire la pagina ProductDetails.aspx e individuare la casella di testo Descrizione .
Aggiungere la nuova proprietà ValidateRequestMode a TextBox e impostarne il valore su Disabled.
Il nuovo attributo ValidateRequestMode consente di disabilitare la convalida della richiesta in modo granulare in ogni controllo. Ciò è utile quando si vuole usare un input che può ricevere codice HTML, ma si vuole mantenere la convalida funzionante per il resto della pagina.
<p> <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" Cols="60" Rows="8" Text='<%# BindItem.Description %>' ValidateRequestMode="Disabled" /> </p>
Premere F5 per eseguire l'applicazione Web. Aprire di nuovo la pagina di modifica del prodotto e completare una descrizione del prodotto, inclusi i tag HTML. Si noti che è ora possibile aggiungere contenuto HTML alla descrizione.
Richiesta di convalida disabilitata per la descrizione del prodotto
Nota
In un'applicazione di produzione, è necessario purificare il codice HTML immesso dall'utente per assicurarsi che vengano immessi solo tag HTML sicuri (ad esempio, non <sono presenti tag script> ). A tale scopo, è possibile usare Microsoft Web Protection Library.
Modificare di nuovo il prodotto. Digitare codice HTML nel campo Nome e fare clic su Salva. Si noti che la convalida della richiesta è disabilitata solo per il campo Descrizione e il resto dei campi ancora convalidati rispetto al contenuto potenzialmente pericoloso.
Convalida della richiesta abilitata nei campi rimanenti
Web Forms ASP.NET 4.5 include una nuova modalità di convalida delle richieste per eseguire la convalida della richiesta in modo differire. Con la modalità di convalida della richiesta impostata su 4.5, se una parte di codice accede a Request.Form["key"], ASP.NET convalida della richiesta di 4.5 attiverà solo la convalida delle richieste per tale elemento specifico nella raccolta moduli.
Inoltre, ASP.NET 4.5 include ora routine di codifica principali della libreria Microsoft Anti-XSS v4.0. Le routine di codifica Anti-XSS vengono implementate dal nuovo tipo AntiXssEncoder disponibile nel nuovo spazio dei nomi System.Web.Security.AntiXss . Con il parametro encoderType configurato per l'uso di AntiXssEncoder, tutta la codifica di output all'interno di ASP.NET usa automaticamente le nuove routine di codifica.
ASP.NET convalida della richiesta 4.5 supporta anche l'accesso non convalidato ai dati della richiesta. ASP.NET 4.5 aggiunge una nuova proprietà dell'insieme all'oggetto HttpRequest denominato Unvalidated. Quando si passa a HttpRequest.Unvalidated si ha accesso a tutti i dati comuni delle richieste, tra cui Forms, QueryStrings, Cookies, URL e così via.
Oggetto Request.Unvalidated
Nota
Usare la proprietà HttpRequest.Unvalidated con cautela. Assicurarsi di eseguire attentamente la convalida personalizzata sui dati delle richieste non elaborate per assicurarsi che il testo pericoloso non venga arrotondato e sottoposto a rendering a clienti insospettabili.
Esercizio 3: Elaborazione asincrona delle pagine in Web Forms ASP.NET
In questo esercizio verranno introdotte le nuove funzionalità di elaborazione delle pagine asincrone in Web Forms ASP.NET.
Attività 1 - Aggiornamento della pagina dei dettagli del prodotto per caricare e visualizzare immagini
In questa attività si aggiornerà la pagina dei dettagli del prodotto per consentire all'utente di specificare un URL di immagine per il prodotto e visualizzarlo nella visualizzazione di sola lettura. Si creerà una copia locale dell'immagine specificata scaricandola in modo sincrono. Nell'attività successiva si aggiornerà questa implementazione per renderla funzionante in modo asincrono.
Aprire Visual Studio 2012 e caricare la soluzione Begin disponibile in Source\Ex3-Async\Begin dalla cartella del lab. In alternativa, è possibile continuare a lavorare sulla soluzione esistente degli esercizi precedenti.
Se è stata aperta la soluzione Begin fornita, è necessario scaricare alcuni pacchetti NuGet mancanti prima di continuare. A tale scopo, nella Esplora soluzioni fare clic sul progetto WebFormsLab e selezionare Gestisci pacchetti NuGet.
Nella finestra di dialogo Gestisci pacchetti NuGet fare clic su Ripristina per scaricare i pacchetti mancanti.
Compilare infine la soluzione facendo clic su Compila | soluzione.
Nota
Uno dei vantaggi dell'uso di NuGet è che non è necessario spedire tutte le librerie nel progetto, riducendo le dimensioni del progetto. Con NuGet Power Tools, specificando le versioni del pacchetto nel file Packages.config, sarà possibile scaricare tutte le librerie necessarie la prima volta che si esegue il progetto. Questo è il motivo per cui è necessario eseguire questi passaggi dopo aver aperto una soluzione esistente da questo lab.
Aprire l'origine della pagina ProductDetails.aspx e aggiungere un campo nel ItemTemplate di FormView per visualizzare l'immagine del prodotto.
<ItemTemplate> <fieldset> <p><b><asp:Label ID="Label2" runat="server" AssociatedControlID="itemProductName">Name:</asp:Label></b></p> <p><asp:Label runat="server" ID="itemProductName" Text='<%#: Item.ProductName %>' /></p> <p><b><asp:Label ID="Label3" runat="server" AssociatedControlID="itemDescription">Description (HTML):</asp:Label></b></p> <p><asp:Label runat="server" ID="itemDescription" Text='<%# Item.Description %>' /></p> <p><b><asp:Label ID="Label4" runat="server" AssociatedControlID="itemUnitPrice">Price:</asp:Label></b></p> <p><asp:Label runat="server" ID="itemUnitPrice" Text='<%#: Item.UnitPrice %>' /></p> <p><b><asp:Label ID="Label5" runat="server" AssociatedControlID="itemUnitPrice">Image:</asp:Label></b></p> <p> <img src="<%# string.IsNullOrEmpty(Item.ImagePath) ? "/Images/noimage.jpg" : Item.ImagePath %>" alt="Image" /> </p> <br /> <p> <asp:Button ID="Button1" runat="server" CommandName="Edit" Text="Edit" /> <asp:HyperLink NavigateUrl="~/Products.aspx" Text="Back" runat="server" /> </p> </fieldset> </ItemTemplate>
Aggiungere un campo per specificare l'URL dell'immagine nel controllo EditTemplate di FormView.
<fieldset> <p><asp:Label ID="Label2" runat="server" AssociatedControlID="ProductName">Name:</asp:Label></p> <p><asp:TextBox runat="server" ID="ProductName" Text='<%#: BindItem.ProductName %>' /></p> <p><asp:Label ID="Label3" runat="server" AssociatedControlID="Description">Description (HTML):</asp:Label></p> <p> <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" Cols="60" Rows="8" Text='<%# BindItem.Description %>' ValidateRequestMode="Disabled" /> </p> <p><asp:Label ID="Label4" runat="server" AssociatedControlID="UnitPrice">Price:</asp:Label></p> <p><asp:TextBox runat="server" ID="UnitPrice" Text='<%#: BindItem.UnitPrice %>' /></p> <p><asp:Label ID="Label1" runat="server" AssociatedControlID="ImagePath">Image URL:</asp:Label></p> <p><asp:TextBox runat="server" ID="ImagePath" Text='<%#: BindItem.ImagePath %>' /></p> <br /> <p> <asp:Button runat="server" CommandName="Update" Text="Save" /> <asp:Button runat="server" CommandName="Cancel" Text="Cancel" CausesValidation="false" /> </p> </fieldset>
Aprire il file code-behind ProductDetails.aspx.cs e aggiungere le direttive dello spazio dei nomi seguenti.
(Frammento di codice - Lab Web Forms - Ex03 - Spazi dei nomi)
using System.IO; using System.Net; using System.Web;
Creare un metodo UpdateProductImage per archiviare immagini remote nella cartella Immagini locali e aggiornare l'entità prodotto con il nuovo valore della posizione dell'immagine.
(Frammento di codice - Lab Web Forms - Ex03 - UpdateProductImage)
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); using (var wc = new WebClient()) { wc.DownloadFile(imageUrl, Server.MapPath(product.ImagePath)); } } }
Aggiornare il metodo UpdateProduct per chiamare il metodo UpdateProductImage .
(Frammento di codice - Lab Web Forms - Ex03 - UpdateProductImage Call)
public void UpdateProduct(int productId) { var product = this.db.Products.Find(productId); this.TryUpdateModel(product); this.UpdateProductImage(product); if (this.ModelState.IsValid) { this.db.SaveChanges(); } }
Eseguire l'applicazione e provare a caricare un'immagine per un prodotto.
Impostazione di un'immagine per un prodotto
Attività 2 - Aggiunta dell'elaborazione asincrona alla pagina Dettagli prodotto
In questa attività si aggiornerà la pagina dei dettagli del prodotto per renderla funzionante in modo asincrono. Si migliorerà un'attività a esecuzione prolungata, ovvero il processo di download delle immagini, usando ASP.NET 4.5 elaborazione asincrona delle pagine.
I metodi asincroni nelle applicazioni Web possono essere usati per ottimizzare il modo in cui vengono usati i pool di thread ASP.NET. In ASP.NET nel pool di thread sono presenti un numero limitato di thread per partecipare alle richieste, pertanto, quando tutti i thread sono occupati, ASP.NET inizia a rifiutare nuove richieste, invia messaggi di errore dell'applicazione e rende il sito non disponibile.
Le operazioni che richiedono molto tempo nel sito Web sono ottimi candidati per la programmazione asincrona perché occupano il thread assegnato per molto tempo. Sono incluse richieste a esecuzione prolungata, pagine con molti elementi e pagine diversi che richiedono operazioni offline, ad esempio l'esecuzione di query su un database o l'accesso a un server Web esterno. Il vantaggio è che se si usano metodi asincroni per queste operazioni, mentre la pagina viene elaborata, il thread viene liberato e restituito al pool di thread e può essere usato per partecipare a una nuova richiesta di pagina. Ciò significa che la pagina inizierà l'elaborazione in un thread dal pool di thread e potrebbe completare l'elaborazione in un'altra, al termine dell'elaborazione asincrona.
Aprire la pagina ProductDetails.aspx . Aggiungere l'attributo Async nell'elemento Page e impostarlo su true. Questo attributo indica ASP.NET di implementare l'interfaccia IHttpAsyncHandler.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ProductDetails.aspx.cs" Inherits="WebFormsLab.ProductDetails" Async="true" %>
Aggiungere un'etichetta nella parte inferiore della pagina per visualizzare i dettagli dei thread che eseguono la pagina.
<EmptyDataTemplate>Product not found</EmptyDataTemplate> </asp:FormView> <asp:Label ID="threadsMessageLabel" runat="server" /> </asp:Content>
Aprire ProductDetails.aspx.cs e aggiungere le direttive dello spazio dei nomi seguenti.
(Frammento di codice - Lab Web Forms - Ex03 - Spazi dei nomi 2)
using System.Web.UI; using System.Threading;
Modificare il metodo UpdateProductImage per scaricare l'immagine con un'attività asincrona. Si sostituirà il metodo WebClient DownloadFile con il metodo DownloadFileTaskAsync e si includerà la parola chiave await .
(Frammento di codice - Lab Web Forms - Ex03 - UpdateProductImage Async)
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); this.RegisterAsyncTask(new PageAsyncTask(async (t) => { using (var wc = new WebClient()) { await wc.DownloadFileTaskAsync(imageUrl, this.Server.MapPath(product.ImagePath)); } })); } }
RegisterAsyncTask registra una nuova attività asincrona di pagina da eseguire in un thread diverso. Riceve un'espressione lambda con l'attività (t) da eseguire. La parola chiave await nel metodo DownloadFileTaskAsync converte il resto del metodo in un callback richiamato in modo asincrono dopo il completamento del metodo DownloadFileTaskAsync . ASP.NET riprenderà l'esecuzione del metodo mantenendo automaticamente tutti i valori originali della richiesta HTTP. Il nuovo modello di programmazione asincrona in .NET 4.5 consente di scrivere codice asincrono molto simile al codice sincrono e consentire al compilatore di gestire le complicazioni delle funzioni di callback o del codice di continuazione.
Nota
RegisterAsyncTask e PageAsyncTask erano già disponibili a partire da .NET 2.0. La parola chiave await è una novità del modello di programmazione asincrona .NET 4.5 e può essere usata insieme ai nuovi metodi TaskAsync dell'oggetto WebClient .NET.
Aggiungere il codice per visualizzare i thread in cui è stato avviato e completato l'esecuzione del codice. A tale scopo, aggiornare il metodo UpdateProductImage con il codice seguente.
(Frammento di codice - Lab Web Form - Ex03 - Mostra thread
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); this.RegisterAsyncTask(new PageAsyncTask(async (t) => { var startThread = Thread.CurrentThread.ManagedThreadId; using (var wc = new WebClient()) { await wc.DownloadFileTaskAsync(imageUrl, this.Server.MapPath(product.ImagePath)); } var endThread = Thread.CurrentThread.ManagedThreadId; this.threadsMessageLabel.Text = string.Format("Started on thread: {0}<br /> Finished on thread: {1}", startThread, endThread); })); } }
Aprire il file Web.config del sito Web. Aggiungere la variabile appSetting seguente.
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
Premere F5 per eseguire l'applicazione e caricare un'immagine per il prodotto. Si noti che l'ID thread in cui il codice è stato avviato e completato può essere diverso. Ciò è dovuto al fatto che le attività asincrone vengono eseguite in un thread separato da ASP.NET pool di thread. Al termine dell'attività, ASP.NET reinsegna l'attività nella coda e assegna uno dei thread disponibili.
Download di un'immagine in modo asincrono
Nota
È anche possibile distribuire questa applicazione nell'Appendice B di Azure seguente : Pubblicazione di un'applicazione ASP.NET MVC 4 tramite Distribuzione Web.
Riepilogo
In questo lab pratico sono stati affrontati e illustrati i concetti seguenti:
- Usare espressioni di data binding fortemente tipizzato
- Usare nuove funzionalità di associazione di modelli in Web Form
- Usare provider di valori per il mapping dei dati della pagina ai metodi code-behind
- Usare annotazioni dati per la convalida dell'input utente
- Sfruttare i vantaggi della convalida lato client non invadente con jQuery in Web Form
- Implementare la convalida granulare delle richieste
- Implementare l'elaborazione asincrona delle pagine in Web Form
Appendice A: Installazione di Visual Studio Express 2012 per Web
È possibile installare Microsoft Visual Studio Express 2012 per Il Web o un'altra versione "Express" usando il Installazione guidata piattaforma Web Microsoft. Le istruzioni seguenti illustrano i passaggi necessari per installare Visual Studio Express 2012 per Il Web usando Installazione guidata piattaforma Web Microsoft.
Passare a [/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169](/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169). In alternativa, se è già stato installato Il programma di installazione della piattaforma Web, è possibile aprirlo e cercare il prodotto "Visual Studio Express 2012 for Web con Azure SDK".
Fare clic su Installa ora. Se non si dispone del programma di installazione della piattaforma Web, si verrà reindirizzati per scaricarlo e installarlo per primo.
Dopo aver aperto Il programma di installazione della piattaforma Web, fare clic su Installa per avviare l'installazione.
Installare Visual Studio Express
Leggere tutte le licenze e le condizioni dei prodotti e fare clic su Accetto per continuare.
Accettazione delle condizioni di licenza
Attendere il completamento del processo di download e installazione.
Stato dell'installazione
Al termine dell'installazione, fare clic su Fine.
Installazione completata
Fare clic su Esci per chiudere Programma di installazione piattaforma Web.
Per aprire Visual Studio Express for Web, passare alla schermata Start e iniziare a scrivere "VS Express", quindi fare clic sul riquadro VS Express for Web.
Riquadro di VS Express per Il Web
Appendice B: Pubblicazione di un'applicazione MVC 4 ASP.NET tramite distribuzione Web
Questa appendice illustra come creare un nuovo sito Web dal portale di Azure e pubblicare l'applicazione ottenuta seguendo il lab, sfruttando la funzionalità di pubblicazione Distribuzione Web fornita da Azure.
Attività 1 - Creazione di un nuovo sito Web dal portale di Azure
Passare al portale di gestione di Azure e accedere usando le credenziali Microsoft associate alla sottoscrizione.
Nota
Con Azure è possibile ospitare gratuitamente 10 siti Web ASP.NET e quindi ridimensionare man mano che il traffico cresce. È possibile iscriversi qui.
Accedere al portale
Fare clic su Nuovo sulla barra dei comandi.
Creazione di un nuovo sito Web
Fare clic su Calcolo | sito Web. Selezionare quindi l'opzione Creazione rapida. Specificare un URL disponibile per il nuovo sito Web e fare clic su Crea sito Web.
Nota
Azure è l'host di un'applicazione Web in esecuzione nel cloud che è possibile controllare e gestire. L'opzione Creazione rapida consente di distribuire un'applicazione Web completata in Azure dall'esterno del portale. Non include i passaggi per la configurazione di un database.
Creazione di un nuovo sito Web con creazione rapida
Attendere la creazione del nuovo sito Web.
Dopo aver creato il sito Web, fare clic sul collegamento nella colonna URL . Verificare che il nuovo sito Web funzioni.
Esplorazione del nuovo sito Web
Sito Web in esecuzione
Tornare al portale e fare clic sul nome del sito Web nella colonna Nome per visualizzare le pagine di gestione.
Apertura delle pagine di gestione del sito Web
Nella pagina Dashboard fare clic sul collegamento Download publish profile (Scarica profilo di pubblicazione).
Nota
Il profilo di pubblicazione contiene tutte le informazioni necessarie per pubblicare un'applicazione Web in Azure per ogni metodo di pubblicazione abilitato. Il profilo di pubblicazione contiene gli URL, le credenziali utente e le stringhe di database necessari per connettersi ed eseguire l'autenticazione su ognuno degli endpoint per cui è abilitato un metodo di pubblicazione. Microsoft WebMatrix 2, Microsoft Visual Studio Express per il Web e Microsoft Visual Studio 2012 supportano la lettura dei profili di pubblicazione per automatizzare la configurazione di questi programmi per la pubblicazione di applicazioni Web in Azure.
Download del profilo di pubblicazione del sito Web
Scaricare il file del profilo di pubblicazione in un percorso noto. Più avanti in questo esercizio si vedrà come usare questo file per pubblicare un'applicazione Web in Azure da Visual Studio.
Salvataggio del file del profilo di pubblicazione
Attività 2 - Configurazione del server di database
Se l'applicazione usa i database di SQL Server, sarà necessario creare un server database SQL. Se si vuole distribuire una semplice applicazione che non usa SQL Server, è possibile ignorare questa attività.
È necessario un server database SQL per archiviare il database dell'applicazione. È possibile visualizzare i server database SQL dalla sottoscrizione nel portale di gestione di Azure nel dashboard del server dei database | | SQL. Se non è stato creato un server, è possibile crearne uno usando il pulsante Aggiungi sulla barra dei comandi. Prendere nota del nome del server e dell'URL, del nome di accesso amministratore e della password, perché verranno usati nelle attività successive. Non creare ancora il database, perché verrà creato in una fase successiva.
Dashboard del server database SQL
Nell'attività successiva verrà testata la connessione al database da Visual Studio, per questo motivo è necessario includere l'indirizzo IP locale nell'elenco degli indirizzi IP consentiti del server. A tale scopo, fare clic su Configura, selezionare l'indirizzo IP da Indirizzo IP client corrente e incollarlo nelle caselle di testo Start IP Address and End IP Address (Indirizzo IP iniziale e Indirizzo IP finale) e fare clic sul pulsante .
Aggiunta dell'indirizzo IP client
Dopo aver aggiunto l'indirizzo IP client all'elenco indirizzi IP consentiti, fare clic su Salva per confermare le modifiche.
Conferma modifiche
Attività 3- Pubblicazione di un'applicazione ASP.NET MVC 4 tramite distribuzione Web
Tornare alla soluzione ASP.NET MVC 4. Nella Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto del sito Web e scegliere Pubblica.
Pubblicazione del sito Web
Importare il profilo di pubblicazione salvato nella prima attività.
Importazione del profilo di pubblicazione
Fare clic su Convalida connessione. Al termine della convalida, fare clic su Avanti.
Nota
La convalida viene completata dopo aver visualizzato un segno di spunta verde accanto al pulsante Convalida connessione.
Convalida della connessione
Nella pagina Impostazioni, nella sezione Database, fare clic sul pulsante accanto alla casella di testo della connessione al database, ad esempio DefaultConnection.
Configurazione distribuzione Web
Configurare la connessione al database come indicato di seguito:
Nel nome del server digitare l'URL del server database SQL usando il prefisso tcp: .
In Nome utente digitare il nome di accesso dell'amministratore del server.
In Password digitare la password di accesso dell'amministratore del server.
Digitare un nuovo nome di database.
Configurazione di stringa di connessione di destinazione
Quindi fare clic su OK. Quando viene richiesto di creare il database, fare clic su Sì.
Creazione del database
Il stringa di connessione che verrà usato per connettersi a database SQL in Azure viene visualizzato nella casella di testo Connessione predefinita. Fare clic su Avanti.
Stringa di connessione che punta a database SQL
Nella pagina Anteprima fare clic su Pubblica.
Pubblicazione dell'applicazione Web
Al termine del processo di pubblicazione, il browser predefinito aprirà il sito Web pubblicato.
Appendice C: Uso di frammenti di codice
Con i frammenti di codice è disponibile tutto il codice necessario a portata di mano. Il documento del lab indica esattamente quando è possibile usarli, come illustrato nella figura seguente.
Uso dei frammenti di codice di Visual Studio per inserire codice nel progetto
Per aggiungere un frammento di codice usando la tastiera (solo C#)
- Posizionare il cursore in cui si desidera inserire il codice.
- Iniziare a digitare il nome del frammento (senza spazi o trattini).
- Guardare come IntelliSense visualizza i nomi dei frammenti di codice corrispondenti.
- Selezionare il frammento corretto (o continuare a digitare fino a quando non viene selezionato il nome dell'intero frammento).
- Premere il tasto TAB due volte per inserire il frammento di codice nella posizione del cursore.
Iniziare a digitare il nome del frammento
Premere TAB per selezionare il frammento di codice evidenziato
Premere di nuovo TAB e il frammento di codice verrà espanso
Per aggiungere un frammento di codice usando il mouse (C#, Visual Basic e XML) 1. Fare clic con il pulsante destro del mouse su dove inserire il frammento di codice.
- Selezionare Inserisci frammento di codice seguito da Frammenti di codice personali.
- Selezionare il frammento di codice pertinente dall'elenco facendo clic su di esso.
Fare clic con il pulsante destro del mouse su dove inserire il frammento di codice e selezionare Inserisci frammento
Selezionare il frammento di codice pertinente dall'elenco facendo clic su di esso