Condividi tramite


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

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 rimbalzi 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 Updated 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 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 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 prodotto che non erano di sola lettura devono 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 QuantityPerUnit UpdateParameters 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 "ProductName" della colonna che 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 ProductName campi e UnitPrice in un controllo GridView modificabile. 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 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 i record del ProductName prodotto esistenti di conseguenza ed esegue il commit dell'aggiornamento chiamando il metodo tableAdapterUpdate(), passando l'istanzaProductsRow.UnitPrice

Con questa aggiunta alla ProductsBLL classe, è possibile creare l'interfaccia GridView semplificata. Aprire nella DataModificationEvents.aspx EditInsertDelete cartella e aggiungere un controllo GridView alla pagina. Creare un nuovo ObjectDataSource e configurarlo per l'uso della classe con il ProductsBLL Select() relativo mapping del metodo a GetProducts e Update() il relativo 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 Update() metodo ObjectDataSource all'overload ProductsBLL del nuovo UpdateProduct 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é 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 dallo 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 sono presenti mapping per i metodi e di Insert() ObjectDataSource, non InsertParameters sono presenti sezioni o DeleteParameters .Delete() 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à dal Finestra Proprietà nella 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 in GridView che non corrispondono ai parametri di input per un UpdateProduct overload, verrà generata un'eccezione quando si tenta di aggiornare.

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 per avere campi modificabili solo ProductName per 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, sono disponibili solo due BoundFields in 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à falsegridView su EnableViewState , si rischia di avere utenti simultanei in modo involontario eliminando o modificando 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

Figura 7: Impostare le proprietà e HtmlEncode di DataFormatString conseguenza (fare clic per visualizzare l'immagine UnitPricea 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 proprietà BoundField ApplyFormatInEditMode su true (fare clic per visualizzare l'immagine UnitPricea 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 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, è possibile creare un gestore eventi per l'evento di RowUpdating GridView e analizzarlo come formattato UnitPrice in decimalvaluta.

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 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, 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 separatore 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 NULL i valori nella Products colonna della UnitPrice tabella, è possibile impedire agli utenti di visitare questa pagina specificando un NULL UnitPrice valore. 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 RowUpdating gestore eventi per impostare e.Cancel true e visualizzare un messaggio che spiega perché se il UnitPrice valore nella NewValues raccolta è null.

Per iniziare, aggiungere un controllo Web Etichetta 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 "È 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, progettazione dovrebbe visualizzare il messaggio di avviso in rosso, grassetto, corsivo, dimensioni del carattere di dimensioni superiori a 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 void Page_Load(object sender, EventArgs e)
{
    MustProvideUnitPriceMessage.Visible = false;
}

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 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 NULL UnitPrice di , questa particolare pagina ASP.NET non lo è.

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 Insertinggli eventi , Updatinge 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 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, 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 gridView, deselezionarne Height le proprietà e Width e associarlo all'oggetto 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 il Insert() metodo che punta al AddProduct metodo , ma impostare nuovamente 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 (fare clic per visualizzare l'immagine AddProducta 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>

Riesecuzione della procedura guidata aggiunta alla 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 finestra di progettazione e selezionare questa opzione. Successivamente, impostare il controllo DetailsView in modo che abbia solo due BoundFields , ProductName e UnitPrice - e 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 controllo 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 rebound 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 GridView nella figura 18 non lo mostra, ai campi del prodotto manca l'interfaccia CategoryIDDetailsView , SupplierID, QuantityPerUnite così via vengono assegnati NULL valori di database. Per visualizzare questo problema, seguire questa procedura:

  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

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 si immagini 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-livello e post-livello che vengono generati durante il processo di modifica dei dati. Insert() Quando viene richiamato il relativo metodo, ObjectDataSource genera prima il relativo Inserting evento, quindi chiama il metodo a cui Insert() è stato mappato il relativo metodo e infine genera l'eventoInserted. 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 viene illustrato come impostare a livello di codice il valore di un parametro di input dall'evento di prelivello di ObjectDataSource.

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 all'insieme di parametri (InputParameters) e una proprietà per annullare l'operazione (Cancel).

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, è sufficiente usare : 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 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 la modifica, l'inserimento e l'eliminazione del processo, sia il controllo Web dei dati che ObjectDataSource proseguono diversi eventi 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 all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato all'indirizzo http://ScottOnWriting.NET.

Grazie speciale a

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