Condividi tramite


Analisi degli eventi associati a inserimento, aggiornamento ed eliminazione (VB)

di Scott Mitchell

Scarica PDF

In questa esercitazione si esamineranno gli eventi che si verificano prima, durante e dopo un'operazione di inserimento, aggiornamento o eliminazione di un controllo Web dati ASP.NET. Si vedrà anche come personalizzare l'interfaccia di modifica per aggiornare solo un subset dei campi del prodotto.

Introduzione

Quando si usano le funzionalità di inserimento, modifica o eliminazione predefinite dei controlli GridView, DetailsView o FormView, un'ampia gamma di passaggi transpire quando l'utente finale completa il processo di aggiunta di un nuovo record o l'aggiornamento o l'eliminazione di un record esistente. Come illustrato nell'esercitazione precedente, quando una riga viene modificata in GridView il pulsante Modifica viene sostituito dai pulsanti Aggiorna e Annulla e i BoundFields si trasformano in Caselle di testo. Dopo che l'utente finale aggiorna i dati e fa clic su Aggiorna, vengono eseguiti i passaggi seguenti al postback:

  1. GridView popola l'oggetto UpdateParameters ObjectDataSource con i campi di identificazione univoci del record modificato (tramite la DataKeyNames proprietà ) insieme ai valori immessi dall'utente
  2. GridView richiama il metodo ObjectDataSource Update() , che a sua volta richiama il metodo appropriato nell'oggetto sottostante (ProductsDAL.UpdateProductnell'esercitazione precedente)
  3. I dati sottostanti, che ora includono le modifiche aggiornate, vengono riassegnati al GridView

Durante questa sequenza di passaggi, viene generato un certo numero di eventi, consentendo di creare gestori eventi per aggiungere logica personalizzata, se necessario. Ad esempio, prima del passaggio 1, viene generato l'evento GridView RowUpdating. A questo punto, è possibile annullare la richiesta di aggiornamento se si verifica un errore di convalida. Quando il metodo Update() viene richiamato, viene generato l'evento ObjectDataSource Updating, offrendo la possibilità di aggiungere o personalizzare i valori di qualsiasi dei UpdateParameters. Dopo che il metodo dell'oggetto sottostante dell'ObjectDataSource ha completato l'esecuzione, viene generato l'evento Updated dell'ObjectDataSource. Un gestore eventi per l'evento Updated può esaminare i dettagli sull'operazione di aggiornamento, ad esempio il numero di righe interessate e se si è verificata o meno un'eccezione. Infine, dopo il Passaggio 2, viene generato l'evento RowUpdated di GridView; un gestore di questo evento può esaminare informazioni aggiuntive sull'operazione di aggiornamento appena eseguita.

La figura 1 illustra questa serie di passaggi ed eventi durante l'aggiornamento di un controllo GridView. Il modello di evento nella figura 1 non è univoco per l'aggiornamento con GridView. L'inserimento, l'aggiornamento o l'eliminazione di dati da GridView, DetailsView o FormView causano la stessa sequenza di eventi pre e post-fase sia per il controllo dati Web che per ObjectDataSource.

Una serie di eventi pre e post viene attivata quando si aggiornano i dati in un GridView

Figura 1: Viene attivata una serie di pre-eventi e post-eventi nell'aggiornare i dati in un controllo GridView (fare clic per visualizzare l'immagine a dimensione intera)

In questa esercitazione si esaminerà l'uso di questi eventi per estendere le funzionalità predefinite di inserimento, aggiornamento ed eliminazione dei controlli Web dati ASP.NET. Si vedrà anche come personalizzare l'interfaccia di modifica per aggiornare solo un subset dei campi del prodotto.

Passaggio 1: Aggiornamento dei campi eProductNamediUnitPriceun prodotto

Nelle interfacce di modifica presenti nell'esercitazione precedente, tutti i campi prodotto che non erano di sola lettura dovevano essere inclusi. Se fosse necessario rimuovere un campo da GridView, ad esempio QuantityPerUnit , quando si aggiornano i dati, il controllo Web dati non imposta il valore di QuantityPerUnitUpdateParameters ObjectDataSource. ObjectDataSource passerebbe quindi un valore di Nothing al metodo del Business Logic Layer (BLL) UpdateProduct, il quale modificherebbe la colonna del record di database QuantityPerUnit a un valore di NULL. Analogamente, se un campo obbligatorio, ad esempio ProductName, viene rimosso dall'interfaccia di modifica, l'aggiornamento avrà esito negativo con un'eccezione "La colonna 'ProductName' non consente i valori Null". Il motivo di questo comportamento era dovuto al fatto che ObjectDataSource è stato configurato per chiamare il ProductsBLL metodo della UpdateProduct classe, che prevedeva un parametro di input per ognuno dei campi del prodotto. Pertanto, l'insieme UpdateParameters ObjectDataSource conteneva un parametro per ognuno dei parametri di input del metodo.

Se si vuole fornire un controllo Web dati che consente all'utente finale di aggiornare solo un subset di campi, è necessario impostare a livello di codice i valori mancanti UpdateParameters nel gestore eventi di Updating ObjectDataSource o creare e chiamare un metodo BLL che prevede solo un subset dei campi. Si esaminerà questo secondo approccio.

In particolare, creiamo una pagina che visualizza solo i campi ProductName e UnitPrice in un GridView editabile. L'interfaccia di modifica di GridView consentirà solo all'utente di aggiornare i due campi ProductName visualizzati e UnitPrice. Poiché questa interfaccia di modifica fornisce solo un sottoinsieme dei campi di un prodotto, è necessario creare un ObjectDataSource che usa il metodo BLL UpdateProduct esistente e ha i valori dei campi prodotto mancanti impostati a livello di codice nel Updating relativo gestore eventi oppure è necessario creare un nuovo metodo BLL che prevede solo il subset di campi definiti in GridView. Per questa esercitazione si userà l'ultima opzione e si creerà un overload del UpdateProduct metodo , uno che accetta solo tre parametri di input: productName, unitPricee productID:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, False)> _
    Public Function UpdateProduct(productName As String, _
        unitPrice As Nullable(Of Decimal), productID As Integer) _
        As Boolean

    Dim products As Northwind.ProductsDataTable = _
        Adapter.GetProductByProductID(productID)

    If products.Count = 0 Then
        Return False
    End If

    Dim product As Northwind.ProductsRow = products(0)

    product.ProductName = productName
    If Not unitPrice.HasValue Then
        product.SetUnitPriceNull()
    Else
        product.UnitPrice = unitPrice.Value
    End If

    Dim rowsAffected As Integer = Adapter.Update(product)

    Return rowsAffected = 1
End Function

Analogamente al metodo originale UpdateProduct , questo overload inizia controllando se nel database è presente un prodotto con l'oggetto specificato ProductID. In caso contrario, restituisce False, a indicare che la richiesta di aggiornamento delle informazioni sul prodotto non è riuscita. In caso contrario, aggiorna i campi del record di prodotto esistenti ProductName e UnitPrice di conseguenza ed esegue il commit dell'aggiornamento chiamando il metodo del TableAdapter Update(), passando l'istanza ProductsRow.

Con questa aggiunta alla ProductsBLL classe, è possibile creare l'interfaccia GridView semplificata. Aprire il DataModificationEvents.aspx nella cartella EditInsertDelete e aggiungere un controllo GridView alla pagina. Creare un nuovo ObjectDataSource e configurarlo per utilizzare la classe ProductsBLL con il suo metodo Select() mappato a GetProducts e il metodo Update() mappato al sovraccarico UpdateProduct che accetta solo i parametri di input productName, unitPrice e productID. Nella Figura 2 viene illustrata la Creazione guidata Origine dati quando si esegue la mappatura del metodo Update() al nuovo overload del metodo UpdateProduct della classe ProductsBLL.

Mappare il metodo Update() di ObjectDataSource sul nuovo overload di UpdateProduct

Figura 2: Eseguire il mapping del metodo objectDataSource Update() al nuovo UpdateProduct overload (fare clic per visualizzare l'immagine a dimensione intera)

Poiché l'esempio Insert() richiederà inizialmente solo la possibilità di modificare i dati, ma non di inserire o eliminare record, dedicare qualche istante per indicare in modo esplicito che i metodi e Delete() di ObjectDataSource non devono essere mappati a nessuno dei ProductsBLL metodi della classe passando alle schede INSERT e DELETE e scegliendo (Nessuno) dall'elenco a discesa.

Scegliere (Nessuno) dall'elenco a discesa per le schede INSERT e DELETE

Figura 3: Scegliere (Nessuno) dall'elenco a discesa per le schede INSERT e DELETE (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver completato questa procedura guidata, selezionare la casella di controllo Abilita modifica dal Smart Tag GridView.

Dopo aver completato la procedura guidata Crea origine dati e associandola a GridView, Visual Studio ha creato la sintassi dichiarativa per entrambi i controlli. Passare alla visualizzazione Origine per esaminare il markup dichiarativo di ObjectDataSource, illustrato di seguito:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Poiché non ci sono mapping per i metodi Insert() e Delete() di ObjectDataSource, non ci sono sezioni InsertParameters o DeleteParameters. Inoltre, poiché il Update() metodo viene mappato all'overload del UpdateProduct metodo che accetta solo tre parametri di input, la UpdateParameters sezione ha solo tre Parameter istanze.

Si noti che la proprietà di OldValuesParameterFormatString ObjectDataSource è impostata su original_{0}. Questa proprietà viene impostata automaticamente da Visual Studio quando si usa la procedura guidata Configura origine dati. Tuttavia, poiché i metodi BLL non prevedono che il valore originale ProductID venga passato, rimuovere completamente questa assegnazione di proprietà dalla sintassi dichiarativa di ObjectDataSource.

Nota

Se si cancella semplicemente il valore della OldValuesParameterFormatString proprietà dalla finestra Proprietà in visualizzazione progettazione, la proprietà sarà ancora presente nella sintassi dichiarativa, ma verrà impostata su una stringa vuota. Rimuovere completamente la proprietà dalla sintassi dichiarativa oppure, dal Finestra Proprietà, impostare il valore sul valore predefinito. {0}

Anche se ObjectDataSource ha UpdateParameters solo per il nome, il prezzo e l'ID del prodotto, Visual Studio ha aggiunto un oggetto BoundField o CheckBoxField in GridView per ognuno dei campi del prodotto.

GridView contiene un campo BoundField o CheckBoxField per ognuno dei campi del prodotto

Figura 4: GridView contiene un campo BoundField o CheckBoxField per ognuno dei campi del prodotto (fare clic per visualizzare l'immagine a dimensione intera)

Quando l'utente finale modifica un prodotto e fa clic sul pulsante Aggiorna, GridView enumera i campi che non erano di sola lettura. Imposta quindi il valore del parametro corrispondente nell'insieme UpdateParameters ObjectDataSource sul valore immesso dall'utente. Se non è presente un parametro corrispondente, GridView ne aggiunge uno alla raccolta. Pertanto, se GridView contiene BoundFields e CheckBoxFields per tutti i campi del prodotto, ObjectDataSource richiamerà l'overload UpdateProduct che accetta tutti questi parametri, nonostante il fatto che il markup dichiarativo di ObjectDataSource specifichi solo tre parametri di input (vedere la figura 5). Analogamente, se è presente una combinazione di campi di prodotto non di sola lettura nella GridView che non corrispondono ai parametri di input per un overload UpdateProduct, verrà generata un'eccezione quando si tenta di eseguire un aggiornamento.

GridView aggiungerà parametri all'insieme UpdateParameters di ObjectDataSource

Figura 5: GridView aggiungerà parametri alla raccolta di UpdateParameters ObjectDataSource (fare clic per visualizzare l'immagine a dimensione intera)

Per assicurarsi che ObjectDataSource richiami l'overload UpdateProduct che accetta solo il nome, il prezzo e l'ID del prodotto, è necessario limitare GridView ai campi modificabili solo per ProductName e UnitPrice. A tale scopo, è possibile rimuovere le altre proprietà BoundFields e CheckBoxFields impostando la proprietà di ReadOnly tali altri campi su Trueo tramite una combinazione dei due campi. Per questa esercitazione è sufficiente rimuovere tutti i campi GridView ad eccezione di ProductName e UnitPrice BoundFields, dopo di che il markup dichiarativo di GridView sarà simile al seguente:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

Anche se l'overload UpdateProduct prevede tre parametri di input, abbiamo solo due BoundFields nella GridView. Questo perché il productID parametro di input è un valore di chiave primaria e passato tramite il valore della DataKeyNames proprietà per la riga modificata.

GridView, insieme all'overload UpdateProduct , consente a un utente di modificare solo il nome e il prezzo di un prodotto senza perdere alcun altro campo prodotto.

L'interfaccia consente di modificare solo il nome e il prezzo del prodotto

Figura 6: L'interfaccia consente di modificare solo il nome e il prezzo del prodotto (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Come illustrato nell'esercitazione precedente, è fondamentale abilitare lo stato di visualizzazione di GridView (comportamento predefinito). Se si imposta la proprietà EnableViewStategridView su false, c'è il rischio che utenti concorrenti eliminino o modifichino involontariamente i record.

Miglioramento dellaUnitPriceformattazione

Mentre l'esempio GridView illustrato nella figura 6 funziona, il UnitPrice campo non è formattato affatto, con conseguente visualizzazione dei prezzi che non contiene simboli di valuta e ha quattro posizioni decimali. Per applicare una formattazione di valuta per le righe non modificabili, è sufficiente impostare la UnitPrice proprietà BoundField DataFormatString su {0:c} e la relativa HtmlEncode proprietà su False.

Impostare di conseguenza le proprietà DataFormatString e HtmlEncode di UnitPrice

: Impostare le proprietà di e di di conseguenza (fare clic per visualizzare l'immagine a piena dimensione)

Con questa modifica, le righe non modificabili formattano il prezzo come valuta; la riga modificata, tuttavia, visualizza comunque il valore senza il simbolo di valuta e con quattro posizioni decimali.

Le righe non modificabili sono ora formattate come valori di valuta

Figura 8: Le righe non modificabili sono ora formattate come valori di valuta (fare clic per visualizzare l'immagine a dimensione intera)

Le istruzioni di formattazione specificate nella DataFormatString proprietà possono essere applicate all'interfaccia di modifica impostando la proprietà BoundField ApplyFormatInEditMode su True (il valore predefinito è False). Prenditi un momento per impostare questa proprietà su True.

Impostare la proprietà ApplyFormatInEditMode di UnitPrice BoundField su True

Figura 9: Impostare la proprietà BoundField UnitPrice su ApplyFormatInEditMode (fare clic per visualizzare l'immagine Truea dimensione intera)

Con questa modifica, anche il valore dell'oggetto UnitPrice visualizzato nella riga modificata viene formattato come valuta.

Screenshot del

Figura 10: Il valore della UnitPrice riga modificata è ora formattato come valuta (fare clic per visualizzare l'immagine a dimensione intera)

Tuttavia, l'aggiornamento di un prodotto con il simbolo di valuta nella casella di testo, ad esempio $19,00 genera un'eccezione FormatException. Quando GridView tenta di assegnare i valori forniti dall'utente all'insieme UpdateParameters ObjectDataSource, non è in grado di convertire la UnitPrice stringa "$19.00" nell'oggetto Decimal richiesto dal parametro (vedere la figura 11). Per risolvere questo problema, possiamo creare un gestore eventi per l'evento RowUpdating di GridView e fare in modo che esso analizzi il UnitPrice fornito dall'utente come un valore formattato in Decimal valuta.

L'evento di RowUpdating GridView accetta come secondo parametro un oggetto di tipo GridViewUpdateEventArgs, che include un NewValues dizionario come una delle relative proprietà che contiene i valori forniti dall'utente pronti per essere assegnati all'insieme UpdateParameters ObjectDataSource. È possibile sovrascrivere il valore esistente UnitPrice nella collezione NewValues con un valore decimale analizzato utilizzando il formato valuta con le righe di codice seguenti nel gestore eventi RowUpdating.

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating
    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    End If
End Sub

Se l'utente ha fornito un UnitPrice valore (ad esempio "$19.00"), questo valore viene sovrascritto con il valore decimale calcolato da Decimal.Parse, analizzando il valore come valuta. Il decimale verrà analizzato correttamente in caso di simboli di valuta, virgole, punti decimali e così via e usa l'enumerazione NumberStyles nello spazio dei nomi System.Globalization.

La figura 11 mostra entrambi i problemi causati dai simboli di valuta nell'oggetto fornito UnitPricedall'utente, insieme al modo in cui il gestore eventi di RowUpdating GridView può essere utilizzato per analizzare correttamente tale input.

Diagramma che mostra come ObjectDataSource elabora il campo UnitPrice e come il gestore eventi RowUpdate di GridView converte una stringa in un decimale.

Figura 11: Il valore della UnitPrice riga modificata è ora formattato come valuta (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 2: ProibizioneNULL UnitPrices

Anche se il database è configurato per consentire i valori NULL nella colonna UnitPrice della tabella Products, è possibile impedire agli utenti che visitano questa pagina dal specificare un valore NULLUnitPrice. Ciò significa che se un utente non riesce a immettere un UnitPrice valore durante la modifica di una riga di prodotto, anziché salvare i risultati nel database che si vuole visualizzare un messaggio che informa l'utente che, tramite questa pagina, i prodotti modificati devono avere un prezzo specificato.

L'oggetto GridViewUpdateEventArgs passato al gestore eventi di RowUpdating GridView contiene una Cancel proprietà che, se impostata su True, termina il processo di aggiornamento. Estendere il gestore eventi RowUpdating per impostare e.Cancel su True e visualizzare un messaggio che spiega il motivo se il valore UnitPrice nella raccolta NewValues ha un valore di Nothing.

Per iniziare, aggiungere un Label Web control alla pagina chiamata MustProvideUnitPriceMessage. Questo controllo Etichetta verrà visualizzato se l'utente non riesce a specificare un UnitPrice valore durante l'aggiornamento di un prodotto. Impostare la proprietà dell'etichetta Text su "È necessario specificare un prezzo per il prodotto". È stata creata anche una nuova classe CSS in Styles.css denominata Warning con la definizione seguente:

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

Impostare infine la proprietà dell'etichetta CssClass su Warning. A questo punto, il Designer dovrebbe visualizzare il messaggio di avviso in rosso, grassetto, corsivo e con dimensioni del carattere extra large sopra il GridView, come illustrato nella Figura 12.

Un'etichetta è stata aggiunta sopra GridView

Figura 12: Un'etichetta è stata aggiunta sopra GridView (fare clic per visualizzare l'immagine a dimensione intera)

Per impostazione predefinita, questa etichetta deve essere nascosta, quindi impostarne la Visible proprietà su False nel Page_Load gestore eventi:

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    MustProvideUnitPriceMessage.Visible = False
End Sub

Se l'utente tenta di aggiornare un prodotto senza specificare UnitPrice, si vuole annullare l'aggiornamento e visualizzare l'etichetta di avviso. Aumentare il gestore eventi di RowUpdating GridView come indicato di seguito:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating

    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    Else
        MustProvideUnitPriceMessage.Visible = True

        e.Cancel = True
    End If
End Sub

Se un utente tenta di salvare un prodotto senza specificare un prezzo, l'aggiornamento viene annullato e viene visualizzato un messaggio utile. Anche se il database (e la logica di business) consente NULLUnitPrice, questa particolare pagina ASP.NET non lo consente.

Un utente non può lasciare vuoto UnitPrice

Figura 13: Un utente non può lasciare UnitPrice vuoto (fare clic per visualizzare l'immagine a dimensione intera)

Finora è stato illustrato come usare l'evento gridView per modificare a livello di RowUpdating codice i valori dei parametri assegnati all'insieme UpdateParameters ObjectDataSource e come annullare completamente il processo di aggiornamento. Questi concetti vengono inclusi nei controlli DetailsView e FormView e si applicano anche all'inserimento e all'eliminazione.

Queste attività possono essere eseguite anche a livello di ObjectDataSource tramite gestori eventi per gli eventi Inserting, Updating e Deleting. Questi eventi vengono generati prima che venga richiamato il metodo associato dell'oggetto sottostante e forniscano un'ultima opportunità per modificare la raccolta di parametri di input o annullare l'operazione. I gestori eventi per questi tre eventi vengono passati a un oggetto di tipo ObjectDataSourceMethodEventArgs con due proprietà di interesse:

  • Annulla, che, se impostato su True, annulla l'operazione eseguita
  • InputParameters, che è la raccolta di InsertParameters, UpdateParameterso DeleteParameters, a seconda che il gestore eventi sia per l'evento Inserting, Updatingo Deleting

Per illustrare l'uso dei valori dei parametri a livello di ObjectDataSource, è possibile includere un controllo DetailsView nella pagina che consente agli utenti di aggiungere un nuovo prodotto. Questo controllo DetailsView verrà usato per fornire un'interfaccia per l'aggiunta rapida di un nuovo prodotto al database. Per mantenere un'interfaccia utente coerente quando si aggiunge un nuovo prodotto, è possibile consentire all'utente di immettere solo i valori per i ProductName campi e UnitPrice . Per impostazione predefinita, i valori non specificati nell'interfaccia di inserimento di DetailsView verranno impostati su un NULL valore del database. Tuttavia, è possibile usare l'evento Inserting ObjectDataSource per inserire valori predefiniti diversi, come si vedrà a breve.

Passaggio 3: Fornire un'interfaccia per aggiungere nuovi prodotti

Trascinare un controllo DetailsView dalla casella degli strumenti nella finestra di progettazione sopra al GridView, svuotarne le proprietà Height e Width e collegarlo all'ObjectDataSource già presente nella pagina. Verrà aggiunto un campo BoundField o CheckBoxField per ognuno dei campi del prodotto. Poiché si vuole usare questo controllo DetailsView per aggiungere nuovi prodotti, è necessario selezionare l'opzione Abilita inserimento dallo smart tag; Tuttavia, non esiste questa opzione perché il metodo ObjectDataSource Insert() non è mappato a un metodo nella ProductsBLL classe (tenere presente che questo mapping viene impostato su (Nessuno) quando si configura l'origine dati vedere la figura 3.

Per configurare ObjectDataSource, selezionare il collegamento Configura origine dati dallo smart tag, avviando la procedura guidata. La prima schermata consente di modificare l'oggetto sottostante a cui è associato ObjectDataSource; lasciare impostato su ProductsBLL. Nella schermata successiva sono elencati i mapping dai metodi di ObjectDataSource all'oggetto sottostante. Anche se è stato indicato in modo esplicito che i Insert() metodi e Delete() non devono essere mappati ad alcun metodo, se si passa alle schede INSERT e DELETE si noterà che è presente un mapping. Questo perché i ProductsBLLAddProduct metodi e DeleteProduct usano l'attributo DataObjectMethodAttribute per indicare che sono rispettivamente i metodi predefiniti per Insert() e Delete(). Di conseguenza, la procedura guidata ObjectDataSource seleziona questi valori ogni volta che si esegue la procedura guidata, a meno che non esista un altro valore specificato in modo esplicito.

Lasciare che il metodo Insert() punti al metodo AddProduct, ma reimpostare l'elenco a discesa della scheda DELETE su (Nessuno).

Impostare l'elenco a discesa della scheda INSERT sul metodo AddProduct

Figura 14: Impostare l'elenco a discesa della scheda INSERT sul metodo AddProduct (fare clic per visualizzare l'immagine a dimensione intera)

Impostare l'elenco a discesa della scheda DELETE su (Nessuno)

Figura 15: Impostare l'elenco a discesa della scheda DELETE su (Nessuno) (Fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver apportato queste modifiche, la sintassi dichiarativa di ObjectDataSource verrà espansa per includere una InsertParameters raccolta, come illustrato di seguito:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <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>

Rieseguire la procedura guidata ha riaggiunto la proprietà OldValuesParameterFormatString. Prenditi un momento per cancellare questa proprietà impostandola al valore predefinito ({0}) o rimuovendola del tutto dalla sintassi dichiarativa.

Con ObjectDataSource che fornisce funzionalità di inserimento, lo smart tag detailsView includerà ora la casella di controllo Abilita inserimento; tornare alla finestra di progettazione e selezionare questa opzione. Successivamente, ridurre il controllo DetailsView in modo che abbia solo due BoundField, ProductName e UnitPrice, e il CommandField. A questo punto la sintassi dichiarativa di DetailsView dovrebbe essere simile alla seguente:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

La figura 16 mostra questa pagina quando viene visualizzata tramite un browser a questo punto. Come si può vedere, DetailsView elenca il nome e il prezzo del primo prodotto (Chai). Ciò che vogliamo, tuttavia, è un'interfaccia di inserimento che consente all'utente di aggiungere rapidamente un nuovo prodotto al database.

Il rendering di DetailsView è attualmente in modalità di sola lettura

Figura 16: Il rendering di DetailsView è attualmente in modalità di sola lettura (fare clic per visualizzare l'immagine a dimensione intera)

Per visualizzare DetailsView nella modalità di inserimento, è necessario impostare la DefaultMode proprietà su Inserting. Questo esegue il rendering di DetailsView in modalità di inserimento quando viene visitato per la prima volta e lo mantiene lì dopo l'inserimento di un nuovo record. Come illustrato nella figura 17, tale DetailsView offre un'interfaccia rapida per l'aggiunta di un nuovo record.

DetailsView fornisce un'interfaccia per l'aggiunta rapida di un nuovo prodotto

Figura 17: DetailsView fornisce un'interfaccia per l'aggiunta rapida di un nuovo prodotto (fare clic per visualizzare l'immagine a dimensione intera)

Quando l'utente immette un nome di prodotto e un prezzo (ad esempio "Acme Water" e 1.99, come nella figura 17) e fa clic su Inserisci, viene eseguito un postback e il flusso di lavoro di inserimento inizia, terminando con un nuovo record di prodotto aggiunto al database. DetailsView mantiene l'interfaccia di inserimento e GridView viene ricollegato automaticamente all'origine dati per includere il nuovo prodotto, come illustrato nella Figura 18.

Il prodotto

Figura 18: Il prodotto "Acqua Acme" è stato aggiunto al database

Anche se il GridView nella figura 18 non lo mostra, i campi del prodotto mancanti dall'interfaccia DetailsView, identificati come CategoryID, SupplierID, QuantityPerUnit, e così via, vengono assegnati valori di database NULL. Per verificare questo, eseguire i seguenti passaggi:

  1. Passare a Esplora server in Visual Studio
  2. Espandere il nodo del database NORTHWND.MDF
  3. Fare clic con il pulsante destro del mouse sul nodo della tabella di Products database
  4. Selezionare Mostra i dati della tabella

Verranno elencati tutti i record nella Products tabella. Come illustrato nella figura 19, tutte le colonne del nuovo prodotto diverse da ProductID, ProductNamee UnitPrice hanno NULL valori .

I campi prodotto non forniti in DetailsView sono valori NULL assegnati

Figura 19: I campi prodotto non forniti in DetailsView sono valori assegnati NULL (fare clic per visualizzare l'immagine a dimensione intera)

È possibile specificare un valore predefinito diverso NULL da per uno o più di questi valori di colonna, perché NULL non è l'opzione predefinita migliore o perché la colonna del database stessa non consente NULL s. A tale scopo, è possibile impostare a livello di codice i valori dei parametri della raccolta detailsView InputParameters . Questa assegnazione può essere eseguita nel gestore eventi per l'evento detailsView ItemInserting o l'evento objectDataSource Inserting . Poiché sono già stati esaminati gli eventi pre-livello e post-livello a livello di controllo Web dei dati, si esaminerà ora l'uso degli eventi di ObjectDataSource.

Passaggio 4: Assegnazione di valori aiCategoryIDparametri eSupplierID

Per questa esercitazione immaginiamo che per l'applicazione, quando si aggiunge un nuovo prodotto tramite questa interfaccia, debbano essere assegnati un valore CategoryID e SupplierID entrambi pari a 1. Come accennato in precedenza, ObjectDataSource include una coppia di eventi pre- e post-elaborazione che vengono attivati durante il processo di modifica dei dati. Quando viene richiamato il metodo Insert(), ObjectDataSource genera prima l'evento Inserting, quindi chiama il metodo a cui è stato mappato il metodo Insert() e infine genera l'evento Inserted. Il Inserting gestore eventi offre un'ultima opportunità per modificare i parametri di input o annullare l'operazione in modo definitivo.

Nota

In un'applicazione reale è probabile che si voglia consentire all'utente di specificare la categoria e il fornitore oppure scegliere questo valore in base a alcuni criteri o logica di business (anziché selezionare un ID 1 in modo cieco). Indipendentemente dall'esempio, l'illustrazione mostra come impostare programmaticamente il valore di un parametro di input dall'evento pre-livello di ObjectDataSource.

Prenditi un momento per creare un gestore eventi per l'evento Inserting di ObjectDataSource. Si noti che il secondo parametro di input del gestore eventi è un oggetto di tipo ObjectDataSourceMethodEventArgs, che ha una proprietà per accedere all'insieme di parametri (InputParameters) e una proprietà per annullare l'operazione (Cancel).

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

End Sub

A questo punto, la InputParameters proprietà contiene l'insieme InsertParameters ObjectDataSource con i valori assegnati da DetailsView. Per modificare il valore di uno di questi parametri, è sufficiente usare : e.InputParameters("paramName") = value. Pertanto, per impostare CategoryID e SupplierID su valori di 1, modificare il gestore eventi Inserting come mostrato di seguito:

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

    e.InputParameters("CategoryID") = 1
    e.InputParameters("SupplierID") = 1
End Sub

Questa volta quando si aggiunge un nuovo prodotto (ad esempio Acme Soda), le CategoryID colonne e SupplierID del nuovo prodotto vengono impostate su 1 (vedere la figura 20).

I nuovi prodotti hanno ora i valori CategoryID e SupplierID impostati su 1

Figura 20: I nuovi prodotti hanno CategoryID ora valori e SupplierID impostati su 1 (fare clic per visualizzare l'immagine a dimensione intera)

Riepilogo

Durante i processi di modifica, inserimento ed eliminazione, sia il controllo Web dei dati che l'ObjectDataSource passano attraverso una serie di eventi di pre-livello e post-livello. In questa esercitazione sono stati esaminati gli eventi di prelivello e si è visto come usarli per personalizzare i parametri di input o annullare completamente l'operazione di modifica dei dati sia dal controllo Web dati che dagli eventi di ObjectDataSource. Nell'esercitazione successiva verrà esaminata la creazione e l'uso di gestori eventi per gli eventi post-livello.

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato 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 a mitchell@4GuysFromRolla.com.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da diversi revisori validi. I revisori principali per questo tutorial erano Jackie Goor e Liz Shulok. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.