Analisi degli eventi associati a inserimento, aggiornamento ed eliminazione (C#)
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
UpdateParameters
ObjectDataSource con i campi di identificazione univoci del record modificato (tramite laDataKeyNames
proprietà ) insieme ai valori immessi dall'utente - GridView richiama il metodo ObjectDataSource
Update()
, che a sua volta richiama il metodo appropriato nell'oggetto sottostante (ProductsDAL.UpdateProduct
nell'esercitazione precedente) - 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.
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 eUnitPrice
diProductName
un 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
, unitPrice
e 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 productName
parametri di input , unitPrice
e 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.
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 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.
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.
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 true
o 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.
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à false
gridView su EnableViewState
, si rischia di avere utenti simultanei in modo involontario eliminando o modificando i record.
Miglioramento dellaUnitPrice
formattazione
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
.
Figura 7: Impostare le proprietà e HtmlEncode
di DataFormatString
conseguenza (fare clic per visualizzare l'immagine UnitPrice
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.
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
.
Figura 9: Impostare la proprietà BoundField ApplyFormatInEditMode
su true
(fare clic per visualizzare l'immagine UnitPrice
a 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, è possibile creare un gestore eventi per l'evento di RowUpdating
GridView e analizzarlo come formattato UnitPrice
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 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 UnitPrice
dall'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 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.
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 è.
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 Inserting
gli eventi , 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
,UpdateParameters
oDeleteParameters
, a seconda che il gestore eventi sia per l'eventoInserting
,Updating
oDeleting
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 ProductsBLL
AddProduct
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).
Figura 14: Impostare l'elenco a discesa della scheda INSERT sul metodo (fare clic per visualizzare l'immagine AddProduct
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>
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.
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.
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.
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 CategoryID
DetailsView , SupplierID
, QuantityPerUnit
e così via vengono assegnati NULL
valori di database. Per visualizzare questo problema, seguire questa procedura:
- Passare a Esplora server in Visual Studio
- Espansione del nodo del
NORTHWND.MDF
database - Fare clic con il pulsante destro del mouse sul nodo della tabella di
Products
database - 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
, ProductName
e 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 aiCategoryID
parametri 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).
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.