Condividi tramite


Panoramica dell'inserimento, dell'aggiornamento e dell'eliminazione dei dati (C#)

di Scott Mitchell

Scarica il PDF

In questa esercitazione verrà illustrato come eseguire il mapping dei metodi Insert() di ObjectDataSource, Update() e Delete() ai metodi delle classi BLL, nonché come configurare i controlli GridView, DetailsView e FormView per fornire funzionalità di modifica dei dati.

Introduzione

Negli ultimi anni sono state esaminate diverse esercitazioni su come visualizzare i dati in una pagina ASP.NET usando i controlli GridView, DetailsView e FormView. Questi controlli funzionano semplicemente con i dati forniti a loro. In genere, questi controllano l'accesso ai dati tramite l'uso di un controllo origine dati, ad esempio ObjectDataSource. È stato illustrato come ObjectDataSource funge da proxy tra la pagina ASP.NET e i dati sottostanti. Quando un oggetto GridView deve visualizzare i dati, richiama il metodo ObjectDataSource Select() , che a sua volta richiama un metodo dal livello BLL (Business Logic Layer), che chiama un metodo nella tabella DAL (Data Access Layer) appropriato, che a sua volta invia una SELECT query al database Northwind.

Si ricordi che quando è stato creato TableAdapters nella prima esercitazione, Visual Studio ha aggiunto automaticamente metodi per l'inserimento, l'aggiornamento e l'eliminazione dei dati dalla tabella di database sottostante. Inoltre, in Creazione di un livello di logica di business sono stati progettati metodi nel BLL chiamato in questi metodi di modifica dei dati DAL.

Oltre al Select() relativo metodo, ObjectDataSource include Insert()anche metodi , Update()e Delete() . Come il Select() metodo, questi tre metodi possono essere mappati ai metodi in un oggetto sottostante. Se configurato per inserire, aggiornare o eliminare i dati, i controlli GridView, DetailsView e FormView forniscono un'interfaccia utente per modificare i dati sottostanti. Questa interfaccia utente chiama i Insert()metodi , Update()e Delete() di ObjectDataSource, che richiamano quindi i metodi associati dell'oggetto sottostante (vedere la figura 1).

I metodi Insert(), Update() e Delete() di ObjectDataSource servono come proxy nel BLL

Figura 1: I metodi , e Delete() di Update()ObjectDataSource servono come proxy nel BLL (fare clic per visualizzare l'immagineInsert() full-size)

In questa esercitazione verrà illustrato come eseguire il mapping dei metodi , e Update()Delete() objectDataSource Insert()ai metodi delle classi nel BLL, nonché come configurare i controlli GridView, DetailsView e FormView per fornire funzionalità di modifica dei dati.

Passaggio 1: Creazione delle pagine Web inserimento, aggiornamento ed eliminazione

Prima di iniziare a esplorare come inserire, aggiornare ed eliminare i dati, è necessario prima di tutto creare le pagine ASP.NET nel progetto del sito Web che sarà necessario per questa esercitazione e le successive diverse. Iniziare aggiungendo una nuova cartella denominata EditInsertDelete. Aggiungere quindi le pagine di ASP.NET seguenti a tale cartella, assicurandosi di associare ogni pagina alla Site.master pagina master:

  • Default.aspx
  • Basics.aspx
  • DataModificationEvents.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

Aggiungere le pagine di ASP.NET per le esercitazioni sull'Modification-Related dati

Figura 2: Aggiungere le pagine ASP.NET per le esercitazioni sui dati Modification-Related

Come nelle altre cartelle, Default.aspx nella EditInsertDelete cartella verranno elencate le esercitazioni nella relativa sezione. Tenere presente che il SectionLevelTutorialListing.ascx controllo utente fornisce questa funzionalità. Aggiungere quindi questo controllo utente a Default.aspx trascinandolo dalla Esplora soluzioni nella visualizzazione Progettazione della pagina.

Aggiungere il controllo utente SectionLevelTutorialListing.ascx a Default.aspx

Figura 3: Aggiungere il controllo utente a Default.aspx (Fare clic per visualizzare l'immagineSectionLevelTutorialListing.ascx full-size)

Infine, aggiungere le pagine come voci al Web.sitemap file. In particolare, aggiungere il markup seguente dopo la formattazione <siteMapNode>personalizzata :

<siteMapNode title="Editing, Inserting, and Deleting"
    url="~/EditInsertDelete/Default.aspx"
    description="Samples of Reports that Provide Editing, Inserting,
                  and Deleting Capabilities">
    <siteMapNode url="~/EditInsertDelete/Basics.aspx"
        title="Basics"
        description="Examines the basics of data modification with the
                      GridView, DetailsView, and FormView controls." />
    <siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
        title="Data Modification Events"
        description="Explores the events raised by the ObjectDataSource
                      pertinent to data modification." />
    <siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
        title="Error Handling"
        description="Learn how to gracefully handle exceptions raised
                      during the data modification workflow." />
    <siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
        title="Adding Data Entry Validation"
        description="Help prevent data entry errors by providing validation." />
    <siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
        title="Customize the User Interface"
        description="Customize the editing and inserting user interfaces." />
    <siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
        title="Optimistic Concurrency"
        description="Learn how to help prevent simultaneous users from
                      overwritting one another s changes." />
    <siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
        title="Confirm On Delete"
        description="Prompt a user for confirmation when deleting a record." />
    <siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
        title="Limit Capabilities Based on User"
        description="Learn how to limit the data modification functionality
                      based on the user role or permissions." />
</siteMapNode>

Dopo l'aggiornamento Web.sitemap, passare un momento per visualizzare il sito Web delle esercitazioni tramite un browser. Il menu a sinistra include ora elementi per la modifica, l'inserimento e l'eliminazione di esercitazioni.

La mappa del sito include ora voci per la modifica, l'inserimento e l'eliminazione di esercitazioni

Figura 4: La mappa del sito include ora voci per la modifica, l'inserimento e l'eliminazione di esercitazioni

Passaggio 2: Aggiunta e configurazione del controllo ObjectDataSource

Poiché GridView, DetailsView e FormView differiscono in base alle funzionalità di modifica dei dati e al layout, esaminiamo ognuna singolarmente. Invece di avere ogni controllo usando objectDataSource, è sufficiente creare un singolo oggetto ObjectDataSource che tutti e tre gli esempi di controllo possono condividere.

Aprire la Basics.aspx pagina, trascinare ObjectDataSource dalla casella degli strumenti nella Designer e fare clic sul collegamento Configura origine dati dal relativo smart tag. Poiché è l'unica ProductsBLL classe BLL che fornisce metodi di modifica, inserimento ed eliminazione, configurare ObjectDataSource per usare questa classe.

Configurare ObjectDataSource per usare la classe ProductsBLL

Figura 5: Configurare ObjectDataSource per usare la classe (fare clic per visualizzare l'immagineProductsBLL full-size)

Nella schermata successiva è possibile specificare i metodi della ProductsBLL classe mappati a ObjectDataSource Select(), Insert(), Update()e Delete() selezionando la scheda appropriata e scegliendo il metodo dall'elenco a discesa. Figura 6, che dovrebbe essere familiare da ora, esegue il mapping del metodo ObjectDataSource Select() al ProductsBLL metodo della GetProducts() classe. I Insert()metodi , Update()e Delete() possono essere configurati selezionando la scheda appropriata dall'elenco lungo la parte superiore.

Ottenere l'oggetto ObjectDataSource Restituire tutti i prodotti

Figura 6: Avere l'oggetto ObjectDataSource restituire tutti i prodotti (fare clic per visualizzare l'immagine a dimensioni complete)

Le figure 7, 8 e 9 mostrano le schede UPDATE, INSERT e DELETE di ObjectDataSource. Configurare queste schede in modo che i metodi , Update()e richiamano rispettivamente i Insert()metodi , AddProducte DeleteProduct della UpdateProductProductsBLLDelete() classe.

Eseguire il mapping del metodo Update() di ObjectDataSource al metodo UpdateProduct della classe ProductBLL

Figura 7: Eseguire il mapping del metodo ObjectDataSource Update() al ProductBLL metodo della UpdateProduct classe (fare clic per visualizzare l'immagine full-size)

Eseguire il mapping del metodo Insert() di ObjectDataSource al metodo AddProduct della classe ProductBLL

Figura 8: Eseguire il mapping del metodo ObjectDataSource Insert() al ProductBLL metodo Add Product della classe (fare clic per visualizzare l'immagine full-size)

Eseguire il mapping del metodo Delete() di ObjectDataSource al metodo DeleteProduct della classe ProductBLL

Figura 9: Eseguire il mapping del metodo ObjectDataSource Delete() al ProductBLL metodo della DeleteProduct classe (fare clic per visualizzare l'immagine full-size)

È possibile che gli elenchi a discesa nelle schede UPDATE, INSERT e DELETE abbiano già selezionato questi metodi. Questo è grazie al nostro uso di DataObjectMethodAttribute che decorare i metodi di ProductsBLL. Ad esempio, il metodo DeleteProduct ha la firma seguente:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
    ...
}

L'attributo DataObjectMethodAttribute indica lo scopo di ogni metodo se è per selezionare, inserire, aggiornare o eliminare e se è il valore predefinito. Se questi attributi vengono omessi durante la creazione delle classi BLL, è necessario selezionare manualmente i metodi dalle schede UPDATE, INSERT e DELETE.

Dopo aver verificato che i metodi appropriati ProductsBLL vengano mappati ai metodi , Update()e Delete() di ObjectDataSourceInsert(), fare clic su Fine per completare la procedura guidata.

Esame del markup di ObjectDataSource

Dopo aver configurato ObjectDataSource tramite la procedura guidata, passare alla visualizzazione Origine per esaminare il markup dichiarativo generato. Il <asp:ObjectDataSource> tag specifica l'oggetto sottostante e i metodi da richiamare. Sono inoltre disponibili DeleteParameters, UpdateParameterse InsertParameters che vengono mappati ai parametri di input per i metodi , UpdateProducte DeleteProduct della ProductsBLLAddProductclasse:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <DeleteParameters>
        <asp:Parameter Name="productID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

ObjectDataSource include un parametro per ogni parametro di input per i relativi metodi associati, proprio come un elenco di SelectParameter s è presente quando ObjectDataSource è configurato per chiamare un metodo select che prevede un parametro di input (ad esempio GetProductsByCategoryID(categoryID)). Come si vedrà brevemente, i valori per questi DeleteParameters, UpdateParameterse InsertParameters vengono impostati automaticamente da GridView, DetailsView e FormView prima di richiamare il metodo ObjectDataSource Insert(), Update()o Delete() . Questi valori possono anche essere impostati a livello di codice in base alle esigenze, come illustrato in un'esercitazione futura.

Un effetto collaterale dell'uso della procedura guidata per configurare in ObjectDataSource è che Visual Studio imposta la proprietà OldValuesParameterFormatString su original_{0}. Questo valore della proprietà viene usato per includere i valori originali dei dati modificati ed è utile in due scenari:

  • Se, quando si modifica un record, gli utenti possono modificare il valore della chiave primaria. In questo caso, è necessario specificare sia il nuovo valore della chiave primaria che il valore della chiave primaria originale in modo che il record con il valore della chiave primaria originale sia aggiornato di conseguenza.
  • Quando si usa la concorrenza ottimistica. La concorrenza ottimistica è una tecnica per garantire che due utenti simultanei non sovrascrivono le modifiche di un altro ed è l'argomento per un'esercitazione futura.

La OldValuesParameterFormatString proprietà indica il nome dei parametri di input nei metodi di aggiornamento ed eliminazione dell'oggetto sottostante per i valori originali. Questa proprietà verrà descritta in modo più dettagliato quando si esplora la concorrenza ottimistica. Tuttavia, i metodi BLL non prevedono i valori originali e pertanto è importante rimuovere questa proprietà. Lasciando la OldValuesParameterFormatString proprietà impostata su qualsiasi elemento diverso dal valore predefinito ({0}) si verificherà un errore quando un controllo Web dati tenta di richiamare i metodi o Delete() objectDataSource perché ObjectDataSource Update() tenterà di passare sia i UpdateParameters parametri o DeleteParameters specificati sia quelli specificati che i parametri di valore originali.

Se questo non è terribilmente chiaro in questo momento, non preoccuparti, esamineremo questa proprietà e la relativa utilità in un'esercitazione futura. Per il momento, è sufficiente rimuovere completamente questa dichiarazione di proprietà dalla sintassi dichiarativa o impostare il valore sul valore predefinito ({0}).

Nota

Se si cancella semplicemente il valore della OldValuesParameterFormatString proprietà dalla Finestra Proprietà nella visualizzazione Progettazione, la proprietà esisterà ancora nella sintassi dichiarativa, ma verrà impostata su una stringa vuota. Questo, purtroppo, continuerà a causare lo stesso problema descritto sopra. Pertanto, rimuovere completamente la proprietà dalla sintassi dichiarativa o, dall'Finestra Proprietà, impostare il valore sul valore predefinito, {0}.

Passaggio 3: Aggiunta di un controllo Web dati e configurazione per la modifica dei dati

Dopo aver aggiunto ObjectDataSource alla pagina e configurato, è possibile aggiungere controlli Web dati alla pagina per visualizzare i dati e fornire un mezzo per l'utente finale per modificarlo. Verranno esaminati separatamente GridView, DetailsView e FormView, in quanto questi controlli Web dati differiscono nelle funzionalità e nella configurazione delle modifiche dei dati.

Come vedremo nella parte restante di questo articolo, aggiungendo modifiche molto di base, inserimento ed eliminazione del supporto tramite i controlli GridView, DetailsView e FormView è davvero semplice come controllare un paio di caselle di controllo. Ci sono molte sottigliezze e casi perimetrali nel mondo reale che rendono più coinvolti tali funzionalità rispetto al solo punto e clic. Questa esercitazione, tuttavia, si concentra esclusivamente sulla dimostrazione delle funzionalità di modifica dei dati semplicistiche. Le esercitazioni future esamineranno i problemi che si verificheranno senza dubbio in un'impostazione reale.

Eliminazione di dati da GridView

Iniziare trascinando gridView dalla casella degli strumenti nella Designer. Associare quindi ObjectDataSource a GridView selezionandolo dall'elenco a discesa nello smart tag di GridView. A questo punto il markup dichiarativo di GridView sarà:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName"
            SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
           SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
           SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
           HeaderText="QuantityPerUnit"
           SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
           SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
           HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
           HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
           HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
           HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
           HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
    </Columns>
</asp:GridView>

L'associazione di GridView a ObjectDataSource tramite lo smart tag offre due vantaggi:

  • BoundFields e CheckBoxFields vengono creati automaticamente per ognuno dei campi restituiti da ObjectDataSource. Inoltre, le proprietà BoundField e CheckBoxField vengono impostate in base ai metadati del campo sottostante. Ad esempio, i ProductIDcampi , CategoryNamee SupplierName sono contrassegnati come di sola lettura in ProductsDataTable e pertanto non devono essere aggiornabili durante la modifica. A tale scopo, queste proprietà ReadOnly di BoundFields sono impostate su true.
  • La proprietà DataKeyNames viene assegnata ai campi della chiave primaria dell'oggetto sottostante. Ciò è essenziale quando si usa GridView per la modifica o l'eliminazione di dati, perché questa proprietà indica il campo (o il set di campi) che identifica ogni record. Per altre informazioni sulla DataKeyNames proprietà, fare riferimento all'esercitazione Master/Detail Using a Selectable Master GridView with a Details DetailView tutorial (Uso di un controllo GridView master selezionabile con dettagli ).

Anche se GridView può essere associato a ObjectDataSource tramite la sintassi Finestra Proprietà o dichiarativa, è necessario aggiungere manualmente il boundField e DataKeyNames il markup appropriati.

Il controllo GridView offre il supporto predefinito per la modifica e l'eliminazione a livello di riga. La configurazione di un controllo GridView per supportare l'eliminazione aggiunge una colonna di pulsanti Elimina. Quando l'utente finale fa clic sul pulsante Elimina per una determinata riga, viene eseguito un postback e GridView esegue i passaggi seguenti:

  1. I valori di DeleteParameters ObjectDataSource vengono assegnati
  2. Viene richiamato il metodo ObjectDataSource Delete() , eliminando il record specificato
  3. GridView si riassocia a ObjectDataSource richiamando il relativo Select() metodo

I valori assegnati a DeleteParameters sono i valori dei DataKeyNames campi della riga su cui è stato fatto clic sul pulsante Elimina. È quindi fondamentale che la proprietà di DataKeyNames GridView sia impostata correttamente. Se manca, all'oggetto DeleteParameters verrà assegnato un null valore nel passaggio 1, che a sua volta non comporterà alcun record eliminato nel passaggio 2.

Nota

La DataKeys raccolta viene archiviata nello stato del controllo gridView, vale a dire che i DataKeys valori verranno memorizzati nel postback anche se lo stato di visualizzazione di GridView è stato disabilitato. Tuttavia, è molto importante che lo stato di visualizzazione rimanga abilitato per GridViews che supportano la modifica o l'eliminazione (comportamento predefinito). Se si imposta la proprietà falsegridView su EnableViewState , il comportamento di modifica ed eliminazione funzionerà correttamente per un singolo utente, ma se sono presenti utenti simultanei che eliminano i dati, esiste la possibilità che questi utenti simultanei possano eliminare o modificare accidentalmente i record che non intendevano.

Questo stesso avviso si applica anche a DetailsViews e FormViews.

Per aggiungere funzionalità di eliminazione a un controllo GridView, è sufficiente passare allo smart tag e selezionare la casella di controllo Abilita eliminazione.

Selezionare la casella di controllo Abilita eliminazione

Figura 10: Selezionare la casella di controllo Abilita eliminazione

Selezionando la casella di controllo Abilita eliminazione dallo smart tag viene aggiunto un campo CommandField a GridView. CommandField esegue il rendering di una colonna in GridView con i pulsanti per eseguire una o più delle attività seguenti: selezione di un record, modifica di un record ed eliminazione di un record. In precedenza è stato visualizzato commandField in azione con la selezione dei record nel master/dettaglio usando un controllo GridView master selezionabile con un'esercitazione DetailsView .

CommandField contiene una serie di ShowXButton proprietà che indicano la serie di pulsanti visualizzati in CommandField. Selezionando la casella di controllo Abilita eliminazione un campo CommandField la cui ShowDeleteButton proprietà è true stata aggiunta all'insieme Columns di GridView.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

A questo punto, crederci o meno, abbiamo finito con l'aggiunta del supporto per l'eliminazione a GridView! Come illustrato nella figura 11, quando si visita questa pagina tramite un browser è presente una colonna dei pulsanti Elimina.

Il campo di comando aggiunge una colonna di pulsanti di eliminazione

Figura 11: Il campo di comando aggiunge una colonna di pulsanti di eliminazione (fare clic per visualizzare l'immagine a dimensione intera)

Se questa esercitazione è stata creata autonomamente, quando si esegue il test di questa pagina facendo clic sul pulsante Elimina verrà generata un'eccezione. Continuare a leggere per informazioni sul motivo per cui sono state generate queste eccezioni e su come risolverle.

Nota

Se si sta seguendo il download a cui si accompagna questa esercitazione, questi problemi sono già stati rilevati. Tuttavia, ti invito a leggere i dettagli elencati di seguito per identificare i problemi che possono verificarsi e soluzioni alternative appropriate.

Se, quando si tenta di eliminare un prodotto, viene visualizzata un'eccezione il cui messaggio è simile a "ObjectDataSource 'ObjectDataSource1' non è stato possibile trovare un metodo non generico 'DeleteProduct' con parametri: productID, original_ProductID", probabilmente si è dimenticato di rimuovere la OldValuesParameterFormatString proprietà da ObjectDataSource. Con la OldValuesParameterFormatString proprietà specificata, ObjectDataSource tenta di passare parametri di input e original_ProductID al productIDDeleteProduct metodo . DeleteProduct, tuttavia, accetta solo un singolo parametro di input, di conseguenza l'eccezione . La rimozione della OldValuesParameterFormatString proprietà (o l'impostazione {0}su ) indica a ObjectDataSource di non tentare di passare il parametro di input originale.

Verificare che la proprietà OldValuesParameterFormatString sia stata cancellata

Figura 12: Verificare che la proprietà sia stata cancellata (fare clic per visualizzare l'immagineOldValuesParameterFormatString a dimensione intera)

Anche se la OldValuesParameterFormatString proprietà è stata rimossa, si otterrà comunque un'eccezione quando si tenta di eliminare un prodotto con il messaggio : "L'istruzione DELETE è in conflitto con il vincolo REFERENCE 'FK_Order_Details_Products'". Il database Northwind contiene un vincolo di chiave esterna tra la Order Details tabella e Products , vale a dire che un prodotto non può essere eliminato dal sistema se nella tabella sono presenti uno o più record Order Details . Poiché ogni prodotto nel database Northwind ha almeno un record in Order Details, non è possibile eliminare alcun prodotto fino a quando non si eliminano prima i record dei dettagli dell'ordine associati del prodotto.

Un vincolo di chiave esterna impedisce l'eliminazione di prodotti

Figura 13: Un vincolo di chiave esterna impedisce l'eliminazione dei prodotti (fare clic per visualizzare l'immagine a dimensione intera)

Per l'esercitazione, è sufficiente eliminare tutti i record dalla Order Details tabella. In un'applicazione reale è necessario:

  • Visualizzare un'altra schermata per gestire le informazioni sui dettagli dell'ordine
  • Aumentare il metodo per includere la DeleteProduct logica per eliminare i dettagli dell'ordine del prodotto specificato
  • Modificare la query SQL usata dall'oggetto TableAdapter per includere l'eliminazione dei dettagli dell'ordine del prodotto specificato

Eliminare tutti i record dalla Order Details tabella per aggirare il vincolo di chiave esterna. Passare a Esplora server in Visual Studio, fare clic con il pulsante destro del NORTHWND.MDF mouse sul nodo e scegliere Nuova query. Quindi, nella finestra di query eseguire l'istruzione SQL seguente: DELETE FROM [Order Details]

Eliminare tutti i record dalla tabella Dettagli ordine

Figura 14: Eliminare tutti i record dalla tabella (fare clic per visualizzare l'immagineOrder Details a dimensione intera)

Dopo aver cancellato la Order Details tabella facendo clic sul pulsante Elimina, il prodotto verrà eliminato senza errori. Se si fa clic sul pulsante Elimina non si elimina il prodotto, verificare che la proprietà gridView DataKeyNames sia impostata sul campo chiave primaria (ProductID).

Nota

Quando si fa clic sul pulsante Elimina viene eseguito un postback e il record viene eliminato. Questo può essere pericoloso perché è facile fare clic accidentalmente sul pulsante Elimina della riga sbagliata. In un'esercitazione futura verrà illustrato come aggiungere una conferma lato client durante l'eliminazione di un record.

Modifica dei dati con GridView

Oltre all'eliminazione, il controllo GridView offre anche il supporto predefinito per la modifica a livello di riga. La configurazione di un controllo GridView per supportare la modifica aggiunge una colonna di pulsanti Modifica. Dal punto di vista dell'utente finale, facendo clic sul pulsante Modifica di una riga, la riga diventa modificabile, trasformando le celle in caselle di testo contenenti i valori esistenti e sostituendo il pulsante Modifica con i pulsanti Aggiorna e Annulla. Dopo aver apportato le modifiche desiderate, l'utente finale può fare clic sul pulsante Aggiorna per confermare le modifiche o il pulsante Annulla per eliminarle. In entrambi i casi, dopo aver fatto clic su Aggiorna o Annulla GridView torna allo stato di pre-modifica.

Dal punto di vista dello sviluppatore di pagine, quando l'utente finale fa clic sul pulsante Modifica per una determinata riga, viene eseguito un postback e GridView esegue i passaggi seguenti:

  1. La proprietà di EditItemIndex GridView viene assegnata all'indice della riga su cui è stato fatto clic sul pulsante Modifica
  2. GridView si riassocia a ObjectDataSource richiamando il relativo Select() metodo
  3. Il rendering dell'indice di riga corrispondente a EditItemIndex viene eseguito in modalità di modifica. In questa modalità, il pulsante Modifica viene sostituito dai pulsanti Update e Cancel e BoundFields le cui ReadOnly proprietà sono False (impostazione predefinita) vengono visualizzate come controlli Web TextBox le cui Text proprietà vengono assegnate ai valori dei campi dati.

A questo punto il markup viene restituito al browser, consentendo all'utente finale di apportare modifiche ai dati della riga. Quando l'utente fa clic sul pulsante Aggiorna, si verifica un postback e GridView esegue i passaggi seguenti:

  1. Ai valori di UpdateParameters ObjectDataSource vengono assegnati i valori immessi dall'utente finale nell'interfaccia di modifica di GridView
  2. Viene richiamato il metodo ObjectDataSource Update() , aggiornando il record specificato
  3. GridView si riassocia a ObjectDataSource richiamando il relativo Select() metodo

I valori della chiave primaria assegnati a UpdateParameters in Step 1 provengono dai valori specificati nella DataKeyNames proprietà , mentre i valori di chiave non primaria provengono dal testo nei controlli Web TextBox per la riga modificata. Come per l'eliminazione, è fondamentale che la proprietà di DataKeyNames GridView sia impostata correttamente. Se manca, al valore della UpdateParameters chiave primaria verrà assegnato un null valore nel passaggio 1, che a sua volta non comporterà alcun record aggiornato nel passaggio 2.

È possibile attivare la funzionalità di modifica semplicemente selezionando la casella di controllo Abilita modifica nello smart tag di GridView.

Selezionare la casella di controllo Abilita modifica

Figura 15: Selezionare la casella di controllo Abilita modifica

Se necessario, selezionare la casella di controllo Abilita modifica aggiungerà un campo command (se necessario) e imposterà la relativa ShowEditButton proprietà su true. Come illustrato in precedenza, commandField contiene una serie di ShowXButton proprietà che indicano la serie di pulsanti visualizzati in CommandField. Selezionando la casella di controllo Abilita modifica, la ShowEditButton proprietà viene aggiunta al campo CommandField esistente:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

Questo è tutto quello che c'è da aggiungere supporto per la modifica rudimentale. Come illustrato nella figura 16, l'interfaccia di modifica è piuttosto grezza per ogni BoundField la cui ReadOnly proprietà è impostata su false (impostazione predefinita) viene eseguito il rendering come textBox. Sono inclusi campi come CategoryID e SupplierID, che sono chiavi di altre tabelle.

Facendo clic sul pulsante Modifica di Chai viene visualizzata la riga in modalità di modifica

Figura 16: Facendo clic sul pulsante Modifica di Chai viene visualizzata la riga in modalità di modifica (fare clic per visualizzare l'immagine a dimensione intera)

Oltre a chiedere agli utenti di modificare direttamente i valori di chiave esterna, l'interfaccia dell'interfaccia di modifica non è presente nei modi seguenti:

  • Se l'utente immette un CategoryID oggetto o SupplierID che non esiste nel database, UPDATE viola un vincolo di chiave esterna, causando la generazione di un'eccezione.
  • L'interfaccia di modifica non include alcuna convalida. Se non si specifica un valore obbligatorio (ad esempio ProductName) o si immette un valore stringa in cui è previsto un valore numerico, ad esempio immettendo "Troppo!" nella UnitPrice casella di testo, verrà generata un'eccezione. Un'esercitazione futura esaminerà come aggiungere controlli di convalida all'interfaccia utente di modifica.
  • Attualmente, tutti i campi del prodotto non di sola lettura devono essere inclusi in GridView. Se si rimuovesse un campo da GridView, ad esempio UnitPrice, quando si aggiornano i dati, GridView non imposterebbe ilUpdateParametersUnitPricevalore, che cambierebbe il record del UnitPrice database su un NULL valore. Analogamente, se un campo obbligatorio, ad esempio ProductName, viene rimosso da GridView, l'aggiornamento avrà esito negativo con la stessa eccezione "Column 'ProductName' does not allow nulls" menzionata in precedenza.
  • La formattazione dell'interfaccia di modifica lascia molto da desiderare. Viene UnitPrice visualizzato con quattro punti decimali. Idealmente, i CategoryID valori e SupplierID contengono elenchi DropDownList che elencano le categorie e i fornitori nel sistema.

Si tratta di tutte le carenze con cui si dovrà vivere per il momento, ma verranno risolte nelle esercitazioni future.

Inserimento, modifica ed eliminazione di dati con DetailsView

Come illustrato nelle esercitazioni precedenti, il controllo DetailsView visualizza un record alla volta e, come GridView, consente di modificare ed eliminare il record attualmente visualizzato. Sia l'esperienza dell'utente finale con la modifica che l'eliminazione di elementi da un controllo DetailsView e il flusso di lavoro dal lato ASP.NET è identico a quello di GridView. Dove DetailsView differisce da GridView è che fornisce anche il supporto predefinito per l'inserimento.

Per illustrare le funzionalità di modifica dei dati di GridView, iniziare aggiungendo un controllo DetailsView alla Basics.aspx pagina sopra l'oggetto GridView esistente e associandolo all'oggetto ObjectDataSource esistente tramite lo smart tag detailsView. Deselezionare quindi le proprietà e Width detailsView Height e selezionare l'opzione Abilita paging dallo smart tag. Per abilitare la modifica, l'inserimento e l'eliminazione del supporto, selezionare semplicemente le caselle di controllo Abilita modifica, Abilita inserimento e Abilita eliminazione nello smart tag.

Screenshot che mostra la finestra DetailsView Tasks con le caselle di controllo Abilita inserimento, Abilita modifica e Abilita eliminazione selezionata.

Figura 17: Configurare DetailsView per supportare la modifica, l'inserimento e l'eliminazione

Come per GridView, l'aggiunta di modifiche, inserimento o eliminazione del supporto aggiunge un campo CommandField a DetailsView, come illustrato nella sintassi dichiarativa seguente:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
    <Fields>
        <asp:BoundField DataField="ProductID"
            HeaderText="ProductID" InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName"
            HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
            SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
            HeaderText="QuantityPerUnit"
            SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
            HeaderText="UnitPrice" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
            HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
            HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
            HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
            HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
            HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Si noti che per DetailsView l'oggetto CommandField viene visualizzato alla fine dell'insieme Columns per impostazione predefinita. Poiché il rendering dei campi di DetailsView viene eseguito come righe, il campo di comando viene visualizzato come riga con i pulsanti Inserisci, Modifica ed Elimina nella parte inferiore di DetailsView.

Screenshot di DetailsView con il campo di comando visualizzato come riga inferiore con i pulsanti Inserisci, Modifica ed Elimina.

Figura 18: Configurare DetailsView per supportare la modifica, l'inserimento e l'eliminazione (fare clic per visualizzare l'immagine a dimensione intera)

Facendo clic sul pulsante Elimina viene avviata la stessa sequenza di eventi di GridView: un postback; seguito da DetailsView che popola l'oggetto DeleteParameters ObjectDataSource in base ai DataKeyNames valori e completato con una chiamata al Delete() metodo ObjectDataSource, che rimuove effettivamente il prodotto dal database. La modifica in DetailsView funziona anche in modo identico a quello di GridView.

Per l'inserimento, all'utente finale viene visualizzato un pulsante Nuovo che, quando si fa clic, esegue il rendering di DetailsView in "modalità di inserimento". Con la "modalità di inserimento" il pulsante Nuovo viene sostituito dai pulsanti Inserisci e Annulla e vengono visualizzati solo quelli BoundFields la cui InsertVisible proprietà è impostata su true (impostazione predefinita). Tali campi dati identificati come campi di incremento automatico, ad esempio ProductID, hanno la proprietà InsertVisible impostata su false quando si associa DetailsView all'origine dati tramite lo smart tag.

Quando si associa un'origine dati a un controllo DetailsView tramite lo smart tag, Visual Studio imposta la InsertVisible proprietà false su solo per i campi di incremento automatico. I campi di sola lettura, ad esempio CategoryName e SupplierName, verranno visualizzati nell'interfaccia utente "modalità di inserimento", a meno che la relativa InsertVisible proprietà non sia impostata in modo esplicito su false. Per impostare le proprietà di InsertVisible questi due campi su false, usare la sintassi dichiarativa di DetailsView o il collegamento Modifica campi nello smart tag. La figura 19 mostra l'impostazione delle InsertVisible proprietà su false facendo clic sul collegamento Modifica campi.

Screenshot che mostra la finestra Campi con la proprietà InsertVisible impostata su False.

Figura 19: Northwind Traders Now Offers Acme Tea (Fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver impostato le InsertVisible proprietà, visualizzare la Basics.aspx pagina in un browser e fare clic sul pulsante Nuovo. La figura 20 mostra DetailsView quando si aggiunge una nuova bevanda, Acme Tea, alla linea di prodotti.

Screenshot che mostra detailsView della pagina Basics.aspx in un Web browser.

Figura 20: Northwind Traders Now Offers Acme Tea (Fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver immesso i dettagli per Acme Tea e aver fatto clic sul pulsante Inserisci, viene eseguito un postback e il nuovo record viene aggiunto alla tabella di Products database. Poiché questo controllo DetailsView elenca i prodotti in ordine con cui sono presenti nella tabella di database, è necessario visualizzare l'ultimo prodotto per visualizzare il nuovo prodotto.

Dettagli per Acme Tea

Figura 21: Dettagli per Acme Tea (fare clic per visualizzare l'immagine a dimensione intera)

Nota

La proprietà CurrentMode di DetailsView indica l'interfaccia visualizzata e può essere uno dei valori seguenti: Edit, Inserto ReadOnly. La proprietà DefaultMode indica la modalità in cui detailsView torna dopo il completamento di una modifica o di un inserimento ed è utile per visualizzare un controllo DetailsView in modalità di modifica o inserimento permanente.

Il punto e fare clic sulle funzionalità di inserimento e modifica di DetailsView subisce le stesse limitazioni di GridView: l'utente deve immettere valori esistenti CategoryID e SupplierID tramite una casella di testo; l'interfaccia non dispone di logica di convalida; tutti i campi di prodotto che non consentono NULL valori o non hanno un valore predefinito specificato a livello di database devono essere inclusi nell'interfaccia di inserimento, E così via.

Le tecniche che esamineremo per estendere e migliorare l'interfaccia di modifica di GridView negli articoli futuri possono essere applicate anche alle interfacce di modifica e inserimento del controllo DetailsView.

Uso di FormView per un'interfaccia utente di modifica dei dati più flessibile

FormView offre il supporto predefinito per l'inserimento, la modifica e l'eliminazione dei dati, ma poiché usa modelli anziché campi non esiste alcuna posizione per aggiungere BoundFields o commandField usati dai controlli GridView e DetailsView per fornire l'interfaccia di modifica dei dati. In alternativa, questa interfaccia consente ai controlli Web di raccogliere l'input dell'utente quando si aggiunge un nuovo elemento o ne modifica uno esistente insieme ai pulsanti Nuovo, Modifica, Elimina, Inserisci, Aggiorna e Annulla devono essere aggiunti manualmente ai modelli appropriati. Fortunatamente, Visual Studio creerà automaticamente l'interfaccia necessaria quando si associa FormView a un'origine dati tramite l'elenco a discesa nello smart tag.

Per illustrare queste tecniche, iniziare aggiungendo un controllo FormView alla Basics.aspx pagina e, dallo smart tag di FormView, associarlo all'oggetto ObjectDataSource già creato. Verrà generato un EditItemTemplatecontrollo , InsertItemTemplatee ItemTemplate per FormView con controlli Web TextBox per raccogliere i controlli Web input e Button dell'utente per i pulsanti New, Edit, Delete, Insert, Update e Cancel. Inoltre, la proprietà di DataKeyNames FormView viene impostata sul campo chiave primaria (ProductID) dell'oggetto restituito da ObjectDataSource. Infine, selezionare l'opzione Abilita paging nello smart tag di FormView.

Di seguito viene illustrato il markup dichiarativo per formView ItemTemplate dopo che FormView è stato associato a ObjectDataSource. Per impostazione predefinita, ogni campo prodotto valore non booleano è associato alla Text proprietà di un controllo Web Etichetta mentre ogni campo valore booleano (Discontinued) è associato alla Checked proprietà di un controllo Web CheckBox disabilitato. Per fare in modo che i pulsanti New, Edit e Delete attivino determinati comportamenti di FormView quando si fa clic, è fondamentale che i valori CommandName siano impostati rispettivamente su New, Edite Delete.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel" runat="server"
            Text='<%# Eval("ProductID") %>'></asp:Label><br />
        ProductName:
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        SupplierID:
        <asp:Label ID="SupplierIDLabel" runat="server"
            Text='<%# Bind("SupplierID") %>'>
        </asp:Label><br />
        CategoryID:
        <asp:Label ID="CategoryIDLabel" runat="server"
            Text='<%# Bind("CategoryID") %>'>
        </asp:Label><br />
        QuantityPerUnit:
        <asp:Label ID="QuantityPerUnitLabel" runat="server"
            Text='<%# Bind("QuantityPerUnit") %>'>
        </asp:Label><br />
        UnitPrice:
        <asp:Label ID="UnitPriceLabel" runat="server"
            Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
        UnitsInStock:
        <asp:Label ID="UnitsInStockLabel" runat="server"
            Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label><br />
        UnitsOnOrder:
        <asp:Label ID="UnitsOnOrderLabel" runat="server"
            Text='<%# Bind("UnitsOnOrder") %>'>
        </asp:Label><br />
        ReorderLevel:
        <asp:Label ID="ReorderLevelLabel" runat="server"
            Text='<%# Bind("ReorderLevel") %>'>
        </asp:Label><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked='<%# Bind("Discontinued") %>'
            Enabled="false" /><br />
        CategoryName:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Bind("CategoryName") %>'>
        </asp:Label><br />
        SupplierName:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Bind("SupplierName") %>'>
        </asp:Label><br />
        <asp:LinkButton ID="EditButton" runat="server"
            CausesValidation="False" CommandName="Edit"
            Text="Edit">
        </asp:LinkButton>
        <asp:LinkButton ID="DeleteButton" runat="server"
            CausesValidation="False" CommandName="Delete"
            Text="Delete">
        </asp:LinkButton>
        <asp:LinkButton ID="NewButton" runat="server"
            CausesValidation="False" CommandName="New"
            Text="New">
        </asp:LinkButton>
    </ItemTemplate>
</asp:FormView>

La figura 22 mostra la visualizzazione di ItemTemplate FormView quando viene visualizzata tramite un browser. Ogni campo prodotto è elencato con i pulsanti Nuovo, Modifica ed Elimina nella parte inferiore.

L'elemento Defaut FormViewTemplate Elenchi ogni campo prodotto insieme ai pulsanti Nuovo, Modifica ed Elimina

Figura 22: Defaut FormView ItemTemplate Elenchi ogni campo prodotto insieme ai pulsanti Nuovo, Modifica ed Elimina (fare clic per visualizzare l'immagine a dimensione intera)

Analogamente a GridView e DetailsView, facendo clic sul pulsante Elimina o su qualsiasi pulsante, LinkButton o ImageButton la cui CommandName proprietà è impostata su Delete causa un postback, popola il valore di DeleteParameters ObjectDataSource in base al valore di DataKeyNames FormView e richiama il metodo ObjectDataSource Delete() .

Quando si fa clic sul pulsante Modifica viene eseguito un postback e i dati vengono rimbalzati a EditItemTemplate, che è responsabile del rendering dell'interfaccia di modifica. Questa interfaccia include i controlli Web per la modifica dei dati insieme ai pulsanti Aggiorna e Annulla. L'impostazione predefinita EditItemTemplate generata da Visual Studio contiene un oggetto Label per tutti i campi di incremento automatico (ProductID), un controllo TextBox per ogni campo valore non booleano e un controllo CheckBox per ogni campo valore booleano. Questo comportamento è molto simile ai campi BoundField generati automaticamente nei controlli GridView e DetailsView.

Nota

Un piccolo problema con la generazione automatica di FormView di EditItemTemplate è che esegue il rendering dei controlli Web TextBox per i campi di sola lettura, ad esempio CategoryName e SupplierName. A breve verrà illustrato come tenere conto di questo problema.

I controlli TextBox nell'oggetto EditItemTemplate hanno la relativa Text proprietà associata al valore del campo dati corrispondente usando il databinding bidirezionale. Il databinding bidirezionale, indicato da <%# Bind("dataField") %>, esegue l'associazione dati sia quando si associano dati al modello che quando si popolano i parametri di ObjectDataSource per l'inserimento o la modifica di record. Ovvero, quando l'utente fa clic sul pulsante Modifica da ItemTemplate, il Bind() metodo restituisce il valore del campo dati specificato. Dopo che l'utente apporta le modifiche e fa clic su Aggiorna, i valori inviati che corrispondono ai campi dati specificati tramite Bind() vengono applicati all'oggetto UpdateParametersObjectDataSource. In alternativa, il databinding unidirezionale, indicato da <%# Eval("dataField") %>, recupera solo i valori dei campi dati quando si associano dati al modello e non restituisce i valori immessi dall'utente ai parametri dell'origine dati al postback.

Il markup dichiarativo seguente mostra l'oggetto di EditItemTemplateFormView. Si noti che il Bind() metodo viene usato nella sintassi di associazione dati qui e che i controlli Web Update e Cancel Button hanno le relative CommandName proprietà impostate di conseguenza.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel1" runat="server"
          Text="<%# Eval("ProductID") %>"></asp:Label><br />
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
          Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
          Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
          Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
             Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
             Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="UpdateButton" runat="server"
            CausesValidation="True" CommandName="Update"
            Text="Update">
        </asp:LinkButton>
        <asp:LinkButton ID="UpdateCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

A EditItemTemplatequesto punto, verrà generata un'eccezione se si tenta di usarla. Il problema è che il rendering dei CategoryName campi e SupplierName viene eseguito come controlli Web TextBox in EditItemTemplate. È necessario modificare queste caselle di testo in Etichette o rimuoverle completamente. È sufficiente eliminarli completamente da EditItemTemplate.

La figura 23 mostra FormView in un browser dopo che è stato fatto clic sul pulsante Modifica per Chai. Si noti che i campi e CategoryName visualizzati in ItemTemplate non sono più presenti, come è stato appena rimosso da EditItemTemplate.SupplierName Quando si fa clic sul pulsante Aggiorna, FormView procede nella stessa sequenza di passaggi dei controlli GridView e DetailsView.

Per impostazione predefinita, EditItemTemplate mostra ogni campo prodotto modificabile come casella di testo o checkbox

Figura 23: per impostazione predefinita, mostra EditItemTemplate ogni campo prodotto modificabile come casella di testo o casella di controllo (fare clic per visualizzare l'immagine a dimensione intera)

Quando si fa clic sul pulsante Inserisci, viene eseguito un postback di ItemTemplate FormView. Tuttavia, nessun dato è associato a FormView perché viene aggiunto un nuovo record. L'interfaccia InsertItemTemplate include i controlli Web per l'aggiunta di un nuovo record insieme ai pulsanti Inserisci e Annulla. L'impostazione predefinita InsertItemTemplate generata da Visual Studio contiene un controllo TextBox per ogni campo valore non booleano e un controllo CheckBox per ogni campo valore booleano, simile all'interfaccia generata automaticamente EditItemTemplate. I controlli TextBox hanno la proprietà Text associata al valore del campo dati corrispondente usando l'associazione dati bidirezionale.

Il markup dichiarativo seguente mostra l'oggetto di InsertItemTemplateFormView. Si noti che il Bind() metodo viene usato nella sintassi databinding qui e che i controlli Web Insert e Cancel Button hanno le relative CommandName proprietà impostate di conseguenza.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
           Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
           Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
           Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
           Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
            Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
           Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="InsertButton" runat="server"
            CausesValidation="True" CommandName="Insert"
            Text="Insert">
        </asp:LinkButton>
        <asp:LinkButton ID="InsertCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

C'è una sottigliezza con la generazione automatica di FormView di InsertItemTemplate. In particolare, i controlli Web TextBox vengono creati anche per i campi di sola lettura, ad esempio CategoryName e SupplierName. EditItemTemplateAnalogamente a , è necessario rimuovere questi textBox da InsertItemTemplate.

La figura 24 mostra FormView in un browser quando si aggiunge un nuovo prodotto, Acme Coffee. Si noti che i SupplierName campi e CategoryName visualizzati in ItemTemplate non sono più presenti, come è stato appena rimosso. Quando si fa clic sul pulsante Inserisci, FormView procede nella stessa sequenza di passaggi del controllo DetailsView, aggiungendo un nuovo record alla Products tabella. La figura 25 mostra i dettagli del prodotto Acme Coffee in FormView dopo l'inserimento.

InsertItemTemplate determina l'interfaccia di inserimento di FormView

Figura 24: InsertItemTemplate Determina l'interfaccia di inserimento di FormView (fare clic per visualizzare l'immagine a dimensione intera)

I dettagli per Il nuovo prodotto, Acme Coffee, sono visualizzati in FormView

Figura 25: I dettagli per il nuovo prodotto, Acme Coffee, vengono visualizzati in FormView (fare clic per visualizzare l'immagine a dimensione intera)

Separando le interfacce di sola lettura, modifica e inserimento in tre modelli separati, FormView consente un grado di controllo più fine su queste interfacce rispetto a DetailsView e GridView.

Nota

Analogamente a DetailsView, la proprietà di CurrentMode FormView indica l'interfaccia visualizzata e la relativa DefaultMode proprietà indica che la modalità in cui FormView torna dopo il completamento di una modifica o di un inserimento.

Riepilogo

In questa esercitazione sono state esaminate le nozioni di base per l'inserimento, la modifica e l'eliminazione di dati usando GridView, DetailsView e FormView. Tutti e tre questi controlli offrono un certo livello di funzionalità di modifica dei dati predefinite che possono essere usate senza scrivere una singola riga di codice nella pagina ASP.NET grazie ai controlli Web dati e a ObjectDataSource. Tuttavia, il semplice punto e le tecniche di clic eseguono il rendering di un'interfaccia utente di modifica dei dati piuttosto fragile e ingenua. Per fornire la convalida, inserire valori programmatici, gestire normalmente le eccezioni, personalizzare l'interfaccia utente e così via, è necessario basarsi su una serie di tecniche che verranno illustrate nelle esercitazioni successive.

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, disponibile all'indirizzo http://ScottOnWriting.NET.