Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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:
- GridView popola l'oggetto
UpdateParametersObjectDataSource con i campi di identificazione univoci del record modificato (tramite laDataKeyNamesproprietà ) insieme ai valori immessi dall'utente - GridView richiama il metodo ObjectDataSource
Update(), che a sua volta richiama il metodo appropriato nell'oggetto sottostante (ProductsDAL.UpdateProductnell'esercitazione precedente) - 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.
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 passa quindi un valore null al metodo BLL (Business Logic Layer) UpdateProduct, che cambia il valore della colonna del record del database QuantityPerUnit modificato in 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 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 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.
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.
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.
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.
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.
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.
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.
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.
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 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. 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.
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 RowUpdating gestore eventi per impostare e.Cancel a true e visualizzare un messaggio che spiega perché, se il valore UnitPrice nella raccolta NewValues è null.
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.
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 NULLUnitPrice, questa particolare pagina ASP.NET non lo consente.
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,UpdateParametersoDeleteParameters, a seconda che il gestore eventi sia per l'eventoInserting,UpdatingoDeleting
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).
Figura 14: Impostare l'elenco a discesa della scheda INSERT sul metodo AddProduct (fare clic per visualizzare l'immagine a dimensione intera)
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.
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.
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.
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:
- Passare a Esplora server in Visual Studio
- Espandere il nodo del database
NORTHWND.MDF - Fare clic con il pulsante destro del mouse sul nodo della tabella di
Productsdatabase - 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 .
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 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 CategoryID e SupplierID su valori di 1, modificare il gestore eventi Inserting come mostrato di seguito:
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).
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.