Condividi tramite


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

di Scott Mitchell

Scarica il 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 di 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à predefinite di inserimento, modifica o eliminazione di funzionalità dei controlli GridView, DetailsView o FormView, una serie di passaggi traspire 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 Campi bound diventano 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 la proprietà ObjectDataSource UpdateParameters 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.UpdateProduct, nell'esercitazione precedente)
  3. I dati sottostanti, che ora includono le modifiche aggiornate, rebound in 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 Update() metodo viene richiamato, viene generato l'evento ObjectDataSource Updating , offrendo la possibilità di aggiungere o personalizzare i valori di uno qualsiasi di UpdateParameters. Al termine dell'esecuzione del metodo dell'oggetto sottostante di ObjectDataSource, viene generato l'evento ObjectDataSource Updated . 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 di RowUpdated GridView. Un gestore eventi per questo evento può esaminare informazioni aggiuntive sull'operazione di aggiornamento appena eseguita.

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

Viene attivata una serie di eventi pre-e post-eventi durante l'aggiornamento dei dati in un controllo GridView

Figura 1: Viene attivata una serie di eventi pre-e post-eventi durante l'aggiornamento dei dati in un controllo GridView (fare clic per visualizzare un'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 eUnitPricediProductNameun prodotto

Nelle interfacce di modifica dell'esercitazione precedente tutti i campi del prodotto che non erano di sola lettura devono essere inclusi. Se si rimuovesse un campo da GridView, ad esempio QuantityPerUnit , quando si aggiornano i dati il controllo Web dati non imposterebbe il valore di QuantityPerUnitUpdateParameters ObjectDataSource. ObjectDataSource passa quindi un null valore al UpdateProduct metodo BLL (Business Logic Layer), che modifica la colonna del record di QuantityPerUnit database modificato in un NULL valore. Analogamente, se un campo obbligatorio, ad esempio ProductName, viene rimosso dall'interfaccia di modifica, l'aggiornamento avrà esito negativo con un'eccezione "Column 'ProductName' does not allow nulls". Il motivo di questo comportamento è 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 oppure creare e chiamare un metodo BLL che prevede solo un subset dei campi. Esaminiamo questo secondo approccio.

In particolare, verrà creata una pagina che visualizza solo i ProductName campi e UnitPrice in un controllo GridView modificabile. L'interfaccia di modifica di GridView consentirà solo all'utente di aggiornare i due campi visualizzati e ProductNameUnitPrice. Poiché questa interfaccia di modifica fornisce solo un subset di 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 relativo Updating gestore eventi oppure è necessario creare un nuovo metodo BLL che prevede solo il subset di campi definiti in GridView. Per questa esercitazione si userà quest'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 bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;

    Northwind.ProductsRow product = products[0];

    product.ProductName = productName;
    if (unitPrice == null) product.SetUnitPriceNull();
      else product.UnitPrice = unitPrice.Value;

    // Update the product record
    int rowsAffected = Adapter.Update(product);

    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

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 e UnitPrice i record di ProductName prodotto esistenti di conseguenza ed esegue il commit dell'aggiornamento chiamando il metodo tableAdapterUpdate(), passando l'istanzaProductsRow.

Con questa aggiunta alla classe ProductsBLL , è possibile creare l'interfaccia GridView semplificata. Aprire nella DataModificationEvents.aspxEditInsertDelete cartella e aggiungere un controllo GridView alla pagina. Creare un nuovo ObjectDataSource e configurarlo per l'uso della classe con il ProductsBLL relativo Select() mapping dei metodi a GetProducts e il relativo Update() mapping del metodo all'overload UpdateProduct che accetta solo i productNameparametri di input , unitPricee productID . Nella figura 2 viene illustrata la creazione guidata origine dati quando si esegue il mapping del metodo ObjectDataSource Update() al ProductsBLL nuovo UpdateProduct overload del metodo della classe.

Eseguire il mapping del metodo Update() di ObjectDataSource all'overload New UpdateProduct

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

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

Scegliere (Nessuno) Dall'elenco Drop-Down per le schede INSERT e DELETE

Figura 3: Scegliere (nessuno) dall'elenco Drop-Down 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 dallo smart tag di GridView.

Dopo aver completato la creazione guidata origine dati e l'associazione 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 sono presenti mapping per i metodi e di Insert() ObjectDataSource, non InsertParameters sono presenti sezioni o DeleteParameters .Delete() Inoltre, poiché il Update() metodo è 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à ObjectDataSource OldValuesParameterFormatString è 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à nella visualizzazione Struttura, 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 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 in GridView che non corrispondono ai parametri di input per un UpdateProduct overload, verrà generata un'eccezione durante il tentativo di aggiornamento.

GridView aggiungerà parametri all'insieme UpdateParameters di ObjectDataSource

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

Per garantire che ObjectDataSource richiami l'overload UpdateProduct che accetta solo il nome, il prezzo e l'ID del prodotto, è necessario limitare gridView alla presenza di campi modificabili solo ProductName per e UnitPrice. Questa operazione può essere eseguita rimuovendo gli altri BoundFields e CheckBoxFields, impostando la proprietà di ReadOnly tali altri campi su trueo tramite una combinazione dei due. 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, sono disponibili solo due BoundFields in GridView. Il motivo è che 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 altri campi di 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à falsegridView su EnableViewState , si rischia di avere utenti simultanei involontariamente eliminando o modificando i record.

Miglioramento dellaUnitPriceformattazione

Anche se 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

Figura 7: Impostare le proprietà e HtmlEncode di DataFormatString conseguenza (fare clic per visualizzare l'immagineUnitPrice a dimensione intera)

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). Impostare questa proprietà su true.

Impostare la proprietà ApplyFormatInEditMode di UnitPrice BoundField su true

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

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

Screenshot di GridView che mostra il valore UnitPrice della riga modificata formattato come valuta.

Figura 10: il valore della UnitPrice riga modificata è ora formattato come valuta (fare clic per visualizzare l'immagine a dimensioni complete)

Tuttavia, l'aggiornamento di un prodotto con il simbolo di valuta nella casella di testo, ad esempio $ 19,00 genera un FormatExceptionoggetto . Quando GridView tenta di assegnare i valori forniti dall'utente all'insieme ObjectDataSource UpdateParameters non è in grado di convertire la UnitPrice stringa "$19.00" nel decimal parametro richiesto dal parametro (vedere Figura 11). Per risolvere questo problema, è possibile creare un gestore eventi per l'evento gridView e analizzarlo come valuta formattato UnitPricedecimaldall'utenteRowUpdating.

L'evento 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 RowUpdating pronti per essere assegnati all'insieme UpdateParameters ObjectDataSource. È possibile sovrascrivere il valore esistente UnitPrice nella NewValues raccolta con un valore decimale analizzato usando il formato valuta con le righe di codice seguenti nel RowUpdating gestore eventi:

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
  if (e.NewValues["UnitPrice"] != null)
    e.NewValues["UnitPrice"] =
        decimal.Parse(e.NewValues["UnitPrice"].ToString(),
            System.Globalization.NumberStyles.Currency);
}

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. Verrà analizzato correttamente il decimale in caso di simboli di valuta, virgole, punti decimali e così via e si 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 usato per analizzare correttamente tale input.

Diagramma che mostra come ObjectDataSource elabora il campo UnitPrice e il modo in cui 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 dimensioni complete)

Passaggio 2: Non consentitoNULL UnitPrices

Sebbene il database sia configurato per consentire NULL i valori nella Products colonna della UnitPrice tabella, è possibile impedire agli utenti di visitare questa determinata pagina specificando un NULLUnitPrice valore. Ovvero, se un utente non riesce a immettere un UnitPrice valore durante la modifica di una riga del prodotto, anziché salvare i risultati nel database che si vuole visualizzare un messaggio che informa l'utente che, tramite questa pagina, tutti 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 per impostare true e visualizzare un messaggio che spiega perché il RowUpdatingUnitPrice valore nell'insieme NewValues è null.e.Cancel

Iniziare aggiungendo un controllo Web Label alla pagina denominata 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 "Devi fornire 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;
}

Infine, impostare la proprietà dell'etichetta CssClass su Warning. A questo punto, la Designer dovrebbe visualizzare il messaggio di avviso in un carattere rosso, grassetto, corsivo, dimensioni di tipo carattere aggiuntive sopra 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 dimensioni complete)

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

protected void Page_Load(object sender, EventArgs e)
{
    MustProvideUnitPriceMessage.Visible = false;
}

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

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    if (e.NewValues["UnitPrice"] != null)
    {
        e.NewValues["UnitPrice"] =
            decimal.Parse(e.NewValues["UnitPrice"].ToString(),
                System.Globalization.NumberStyles.Currency);
    }
    else
    {
        // Show the Label
        MustProvideUnitPriceMessage.Visible = true;

        // Cancel the update
        e.Cancel = true;
    }
}

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 di usare NULLUnitPrice s, questa determinata pagina ASP.NET non viene visualizzata.

Un utente non può lasciare vuoto UnitPrice

Figura 13: un utente non può lasciare vuoto (fare clic per visualizzareUnitPrice l'immagine full-size)

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

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

  • Annulla, che, se impostato su true, annulla l'operazione eseguita
  • InputParameters, ovvero la raccolta di InsertParameters, UpdateParameterso , a seconda che il gestore eventi sia per InsertingUpdating, o DeleteParametersDeleting evento

Per illustrare l'uso dei valori dei parametri a livello ObjectDataSource, è possibile includere un oggetto DetailsView nella pagina che consente agli utenti di aggiungere un nuovo prodotto. Questo oggetto DetailsView verrà usato per fornire un'interfaccia per aggiungere rapidamente 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, tali valori non forniti 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à brevemente.

Passaggio 3: Fornire un'interfaccia per aggiungere nuovi prodotti

Trascinare detailsView dalla casella degli strumenti nella Designer sopra GridView, cancellarne Height le proprietà e Width e associarla all'oggetto ObjectDataSource già presente nella pagina. Verrà aggiunto un oggetto BoundField o CheckBoxField per ognuno dei campi del prodotto. Poiché si vuole usare Questo controllo DetailsView per aggiungere nuovi prodotti, è necessario controllare l'opzione Abilita inserimento dallo smart tag; Tuttavia, non è disponibile alcuna opzione perché il metodo ObjectDataSource Insert() non viene mappato a un metodo nella ProductsBLL classe (si ricordi che questo mapping viene impostato su (Nessuno) durante la configurazione dell'origine dati vedere la figura 3.

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

Lasciare il metodo che punta al AddProduct metodo, ma impostare di nuovo l'elenco Insert() a discesa della scheda DELETE su (Nessuno).

Impostare l'elenco di Drop-Down della scheda INSERT sul metodo AddProduct

Figura 14: Impostare l'elenco di Drop-Down scheda INSERT sul AddProduct metodo (fare clic per visualizzare l'immagine full-size)

Impostare l'elenco di Drop-Down della scheda DELETE su (Nessuno)

Figura 15: Impostare l'elenco di Drop-Down della scheda DELETE su (Nessuno) (Fare clic per visualizzare l'immagine a dimensioni complete)

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>

Ripetere la procedura guidata ha aggiunto nuovamente la OldValuesParameterFormatString proprietà. Per cancellare questa proprietà, impostarla sul valore predefinito ({0}) o rimuoverla completamente dalla sintassi dichiarativa.

Con objectDataSource che fornisce funzionalità di inserimento, lo smart tag detailsView includerà ora la casella di controllo Abilita inserimento; tornare alla Designer e controllare questa opzione. Successivamente, pare down the DetailsView in modo che abbia solo due BoundFields ProductName - e - e UnitPrice il CommandField. A questo punto la sintassi dichiarativa di DetailsView dovrebbe essere simile a quanto segue:

<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 visualizzata tramite un browser a questo punto. Come si può vedere, DetailsView elenca il nome e il prezzo del primo prodotto (Chai). Ciò che si vuole, tuttavia, è un'interfaccia di inserimento che fornisce un mezzo per l'utente di aggiungere rapidamente un nuovo prodotto al database.

DetailsView è attualmente sottoposto a rendering in modalità Read-Only

Figura 16: Il rendering di DetailsView è attualmente in modalità Read-Only (fare clic per visualizzare l'immagine a dimensioni complete)

Per visualizzare DetailsView nella modalità di inserimento, è necessario impostare la DefaultMode proprietà su Inserting. In questo modo viene eseguito il rendering di DetailsView in modalità di inserimento quando viene prima visitato e lo mantiene lì dopo l'inserimento di un nuovo record. Come illustrato nella figura 17, tale oggetto 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 full-size)

Quando l'utente immette un nome e un prezzo del prodotto ,ad esempio "Acme Water" e 1.99, come nella figura 17) e fa clic su Inserisci, un postback e la commensazione del flusso di lavoro di inserimento, che culmina in un nuovo record di prodotto aggiunto al database. DetailsView mantiene l'interfaccia di inserimento e GridView viene rebound automaticamente all'origine dati per includere il nuovo prodotto, come illustrato nella figura 18.

Prodotto

Figura 18: il prodotto "Acme Water" è stato aggiunto al database

Mentre GridView nella figura 18 non lo mostra, i campi del prodotto mancanti dall'interfaccia CategoryIDDetailsView , SupplierID, QuantityPerUnite così via vengono assegnati NULL valori di database. È possibile visualizzare questa operazione eseguendo la procedura seguente:

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

Verrà elencato 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 del 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 full-size)

È possibile specificare un valore predefinito diverso da NULL per uno o più di questi valori di colonna, perché NULL non è l'opzione predefinita migliore o perché la colonna di database stessa non consente NULL . A tale scopo, è possibile impostare a livello di codice i valori dei parametri dell'insieme InputParameters DetailsView. Questa assegnazione può essere eseguita nel gestore eventi per l'evento DetailsView o l'evento ItemInsertingInserting ObjectDataSource. Poiché è già stato esaminato l'uso degli eventi pre-e post-livello a livello di controllo Web dei dati, è possibile esplorare l'uso degli eventi objectDataSource in questa fase.

Passaggio 4: Assegnazione di valori aiCategoryIDparametri eSupplierID

Per questa esercitazione si supponga che per l'applicazione quando si aggiunge un nuovo prodotto tramite questa interfaccia deve essere assegnato un CategoryID valore e SupplierID pari a 1. Come accennato in precedenza, ObjectDataSource include una coppia di eventi pre-e post-livello che vengono attivati durante il processo di modifica dei dati. Insert() Quando viene richiamato il metodo, ObjectDataSource genera prima il relativo Inserting evento, quindi chiama il metodo a cui Insert() è stato eseguito il mapping del metodo e infine genera l'eventoInserted. Il Inserting gestore eventi consente di modificare i parametri di input o annullare l'operazione in modo definitivo.

Nota

In un'applicazione reale probabilmente si vuole consentire all'utente di specificare la categoria e il fornitore o scegliere questo valore in base a alcuni criteri o logica di business (anziché selezionare in modo cieco un ID di 1). Indipendentemente dal fatto che l'esempio illustra come impostare a livello di codice il valore di un parametro di input dall'evento pre-livello di ObjectDataSource.

È necessario creare un gestore eventi per l'evento Inserting ObjectDataSource. Si noti che il secondo parametro di input del gestore eventi è un oggetto di tipo ObjectDataSourceMethodEventArgs, che ha una proprietà per accedere alla raccolta di parametri () e una proprietà per annullare l'operazione (InputParametersCancel).

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{

}

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, usare semplicemente: e.InputParameters["paramName"] = value. Pertanto, per impostare i CategoryID valori e SupplierID su 1, modificare il Inserting gestore eventi in modo che sia simile al seguente:

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{
    e.InputParameters["CategoryID"] = 1;
    e.InputParameters["SupplierID"] = 1;
}

Questa volta quando si aggiunge un nuovo prodotto (ad esempio Acme Soda), le CategoryID colonne e SupplierID del nuovo prodotto sono 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 ora valori CategoryID e SupplierID impostati su 1 (fare clic per visualizzare l'immagine full-size)

Riepilogo

Durante la modifica, l'inserimento e l'eliminazione del processo, sia il controllo Web dei dati che il controllo ObjectDataSource procede attraverso un numero di eventi pre-e post-livello. In questa esercitazione sono stati esaminati gli eventi prelivello e è stato illustrato come usarli per personalizzare i parametri di input o annullare completamente l'operazione di modifica dei dati dal controllo Web dei dati e dagli eventi objectDataSource. Nell'esercitazione successiva verranno esaminati la creazione e l'uso dei gestori eventi per gli eventi post-livello.

Programmazione felice!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.

Grazie speciali

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali per questa esercitazione sono stati Jackie Goor e Liz Shulok. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.