Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
door Scott Mitchell
In deze zelfstudie bekijken we de gebeurtenissen die plaatsvinden vóór, tijdens en na een invoeg-, update- of verwijderbewerking van een ASP.NET gegevenswebbesturing. We zien ook hoe u de bewerkingsinterface aanpast om alleen een subset van de productvelden bij te werken.
Introductie
Wanneer u de ingebouwde functies voor invoegen, bewerken of verwijderen van de besturingselementen GridView, DetailsView of FormView gebruikt, worden er verschillende stappen uitgevoerd wanneer de eindgebruiker het proces voor het toevoegen van een nieuwe record voltooit of een bestaande record bijwerkt of verwijdert. Zoals we in de vorige zelfstudie hebben besproken, wordt de knop Bewerken vervangen door de knoppen Bijwerken en Annuleren en worden de BoundFields omgezet in Tekstvaken wanneer een rij wordt bewerkt in GridView. Nadat de eindgebruiker de gegevens heeft bijgewerkt en op Update heeft geklikt, worden de volgende stappen uitgevoerd op terugpost:
- De GridView vult de ObjectDataSource's
UpdateParametersmet de unieke identificatievelden van de bewerkte record (via deDataKeyNameseigenschap) samen met de waarden die door de gebruiker zijn ingevoerd - GridView roept de methode van ObjectDataSource
Update()aan, die op zijn beurt de juiste methode aanroept in het onderliggende object (ProductsDAL.UpdateProductin onze vorige zelfstudie) - De onderliggende gegevens, die nu de bijgewerkte wijzigingen bevatten, gaan terug naar de GridView
Tijdens deze reeks stappen wordt een aantal gebeurtenissen geactiveerd, waardoor we gebeurtenis-handlers kunnen maken om waar nodig aangepaste logica toe te voegen. Bijvoorbeeld, vóór stap 1, wordt de gebeurtenis van GridView RowUpdating geactiveerd. Op dit moment kunnen we de updateaanvraag annuleren als er een validatiefout optreedt. Wanneer de Update() methode wordt aangeroepen, wordt de gebeurtenis van Updating ObjectDataSource geactiveerd, waardoor de mogelijkheid wordt geboden om de waarden van een van de UpdateParameterswaarden toe te voegen of aan te passen. Nadat de methode van het onderliggende object van de ObjectDataSource is uitgevoerd, wordt de Updated gebeurtenis van de ObjectDataSource geactiveerd. Een gebeurtenis-handler voor de Updated gebeurtenis kan de details van de updatebewerking controleren, zoals het aantal rijen dat is beïnvloed en of er al dan niet een uitzondering is opgetreden. Ten slotte, nadat stap 2 is voltooid, wordt de gebeurtenis van de GridView RowUpdated geactiveerd. Een gebeurtenis-handler voor deze gebeurtenis kan worden gebruikt om aanvullende informatie te bekijken over de zojuist uitgevoerde updatebewerking.
Afbeelding 1 toont deze reeks gebeurtenissen en stappen bij het bijwerken van een GridView. Het gebeurtenispatroon in afbeelding 1 is niet uniek voor het bijwerken met een GridView. Het invoegen, bijwerken of verwijderen van gegevens uit GridView, DetailsView of FormView precipitaeert dezelfde reeks gebeurtenissen vóór en na niveau voor zowel het gegevenswebbesturingselement als de ObjectDataSource.
Afbeelding 1: Een reeks pre- en postgebeurtenissen wordt geactiveerd bij het bijwerken van gegevens in een GridView (klik hier om de volledige afbeelding weer te geven)
In deze zelfstudie gaan we deze gebeurtenissen gebruiken om de ingebouwde mogelijkheden voor het invoegen, bijwerken en verwijderen van de ASP.NET webbesturingselementen voor gegevens uit te breiden. We zien ook hoe u de bewerkingsinterface aanpast om alleen een subset van de productvelden bij te werken.
Stap 1: Een product en zijn velden bijwerken
In de bewerkingsinterfaces uit de vorige zelfstudie moesten alle productvelden die niet alleen-lezen waren opgenomen. Als we een veld uit GridView zouden verwijderen , bijvoorbeeld QuantityPerUnit wanneer we de gegevens bijwerken, zou het gegevenswebbesturingselement de waarde van QuantityPerUnitUpdateParameters ObjectDataSource niet instellen. De ObjectDataSource geeft vervolgens een null waarde door aan de UpdateProduct methode BLL (Business Logic Layer), waardoor de kolom van QuantityPerUnit de bewerkte databaserecord wordt gewijzigd in een NULL waarde. Wanneer een vereist veld, zoals ProductName, wordt verwijderd uit het bewerkingsscherm, mislukt de update met de uitzondering "De kolom 'ProductName' staat geen null-waarden toe." De reden voor dit gedrag was dat de ObjectDataSource is geconfigureerd om de methode van ProductsBLL de UpdateProduct klasse aan te roepen, die een invoerparameter verwachtte voor elk van de productvelden. Daarom bevat de verzameling van ObjectDataSource UpdateParameters een parameter voor elk van de invoerparameters van de methode.
Als we een gegevenswebbeheer willen bieden waarmee de eindgebruiker alleen een subset velden kan bijwerken, moeten we de ontbrekende UpdateParameters waarden in de gebeurtenis-handler van Updating ObjectDataSource programmatisch instellen of een BLL-methode maken en aanroepen die alleen een subset van de velden verwacht. Laten we deze laatste benadering eens bekijken.
Laten we een pagina maken die alleen de velden ProductName en UnitPrice in een bewerkbare GridView weergeeft. Met de bewerkingsinterface van Deze GridView kan de gebruiker alleen de twee weergegeven velden bijwerken, ProductName en UnitPrice. Omdat deze bewerkingsinterface alleen een subset van de velden van een product biedt, moeten we een ObjectDataSource maken die gebruikmaakt van de bestaande methode van UpdateProduct BLL en waarvoor de ontbrekende productveldwaarden programmatisch zijn ingesteld in de Updating gebeurtenishandler, of we moeten een nieuwe BLL-methode maken die alleen de subset van velden verwacht die zijn gedefinieerd in GridView. Voor deze zelfstudie gebruiken we de laatste optie en maken we een overbelasting van de UpdateProduct methode, een met slechts drie invoerparameters: productName, unitPriceen 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;
}
Net als de oorspronkelijke UpdateProduct methode begint deze overbelasting door te controleren of er een product in de database is met de opgegeven ProductID. Zo niet, dan wordt deze geretourneerd false, waarmee wordt aangegeven dat de aanvraag voor het bijwerken van de productgegevens is mislukt. Anders worden de bestaande productrecords ProductName en UnitPrice -velden dienovereenkomstig bijgewerkt en wordt de update doorgevoerd door de methode van TableAdapter Update() aan te roepen, waarbij het ProductsRow exemplaar wordt doorgegeven.
Met deze toevoeging aan onze ProductsBLL klas zijn we klaar om de vereenvoudigde GridView-interface te maken. Open de DataModificationEvents.aspxEditInsertDelete map en voeg een GridView toe aan de pagina. Maak een nieuwe ObjectDataSource aan en configureer deze om de ProductsBLL klasse te gebruiken, waarbij de Select() methode wordt toegewezen aan GetProducts en de Update() methode aan de UpdateProduct overload die alleen de invoerparameters productName, unitPrice, en productID vereist. Afbeelding 2 toont de wizard Gegevensbron maken bij het koppelen van de methode Update() van de ObjectDataSource aan de nieuwe methodeoverlading ProductsBLL van de klasse UpdateProduct.
Afbeelding 2: Wijs de methode van Update() ObjectDataSource toe aan de nieuwe UpdateProduct overbelasting (klik om de afbeelding op volledige grootte weer te geven)
Omdat in ons voorbeeld in eerste instantie alleen de mogelijkheid nodig is om gegevens te bewerken, maar geen records in te voegen of te verwijderen, moet u expliciet aangeven dat de en methoden van Insert() ObjectDataSource Delete() niet moeten worden toegewezen aan een van de methoden van de ProductsBLL klasse door naar de tabbladen INSERT en DELETE te gaan en (Geen) te kiezen in de vervolgkeuzelijst.
Afbeelding 3: Kies (Geen) in de Drop-Down Lijst voor de tabbladen INVOEGEN en VERWIJDEREN (klik om de afbeelding op volledige grootte weer te geven)
Nadat u deze wizard hebt voltooid, schakelt u het selectievakje Schakel Bewerken in van de smart tag van GridView.
Met de voltooiing van de wizard Gegevensbron maken en die binden aan GridView, heeft Visual Studio de declaratieve syntaxis voor beide besturingselementen gemaakt. Ga naar de bronweergave om de declaratieve markeringen van ObjectDataSource te controleren, die hieronder wordt weergegeven:
<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>
Aangezien er geen mappings zijn voor de methoden Insert() en Delete() van de ObjectDataSource, zijn er geen secties InsertParameters of DeleteParameters. Omdat de Update() methode is toegewezen aan de overbelasting van de UpdateProduct methode die slechts drie invoerparameters accepteert, heeft de UpdateParameters sectie slechts drie Parameter exemplaren.
Houd er rekening mee dat de eigenschap van OldValuesParameterFormatString ObjectDataSource is ingesteld op original_{0}. Deze eigenschap wordt automatisch ingesteld door Visual Studio wanneer u de wizard Gegevensbron configureren gebruikt. Omdat onze BLL-methoden echter niet verwachten dat de oorspronkelijke ProductID waarde wordt doorgegeven, verwijdert u deze eigenschapstoewijzing helemaal uit de declaratieve syntaxis van ObjectDataSource.
Opmerking
Als u de OldValuesParameterFormatString eigenschapswaarde uit het venster Eigenschappen in de Ontwerpweergave wist, bestaat de eigenschap nog steeds in de declaratieve syntaxis, maar wordt deze ingesteld op een lege tekenreeks. Verwijder de eigenschap helemaal uit de declaratieve syntaxis of stel in het venster Eigenschappen de waarde in op de standaardwaarde {0}.
Hoewel ObjectDataSource alleen de naam, prijs en id van het product heeft UpdateParameters , heeft Visual Studio een BoundField- of CheckBoxField-veld toegevoegd in gridview voor elk van de velden van het product.
Afbeelding 4: De GridView bevat een afhankelijk veld of selectievakjeveld voor elk van de velden van het product (klik om de volledige afbeelding weer te geven)
Wanneer de eindgebruiker een product bewerkt en op de knop Bijwerken klikt, worden de velden die niet schrijfbaar waren, opgesomd in de GridView. Vervolgens wordt de waarde van de bijbehorende parameter in de verzameling ObjectDataSource UpdateParameters ingesteld op de waarde die door de gebruiker is ingevoerd. Als er geen bijbehorende parameter is, voegt GridView er een toe aan de verzameling. Dus als onze GridView BoundFields en CheckBoxFields bevat voor alle velden van het product, zal objectDataSource uiteindelijk de UpdateProduct overbelasting aanroepen die al deze parameters inneemt, ondanks het feit dat de declaratieve markeringen van ObjectDataSource slechts drie invoerparameters bevatten (zie afbeelding 5). Op dezelfde manier, indien er een combinatie bestaat van niet-alleen-lezen productvelden in de GridView die niet overeenkomt met de invoerparameters voor een UpdateProduct overload, wordt er een uitzondering gegenereerd wanneer u probeert bij te werken.
Afbeelding 5: De GridView voegt parameters toe aan de verzameling van ObjectDataSource UpdateParameters (klik om de volledige afbeelding weer te geven)
Om ervoor te zorgen dat de ObjectDataSource de UpdateProduct overload aanroept die alleen de naam, prijs en ID van het product gebruikt, moeten we de GridView beperken tot bewerkbare velden voor alleen de velden ProductName en UnitPrice. Dit kan worden bereikt door de andere BoundFields en CheckBoxFields te verwijderen, door de eigenschap van die andere velden ReadOnly in te truestellen op , of door een combinatie van de twee. Voor deze zelfstudie gaan we alle GridView-velden behalve de ProductName en UnitPrice BoundFields verwijderen, waarna de declaratieve markeringen van GridView er als volgt uitzien:
<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>
Hoewel de UpdateProduct overbelasting drie invoerparameters verwacht, hebben we slechts twee BoundFields in onze GridView. Dit komt doordat de productID invoerparameter een primaire-sleutelwaarde is en wordt doorgegeven via de waarde van de DataKeyNames eigenschap voor de bewerkte rij.
Met onze GridView, samen met de UpdateProduct overload-functie, kan een gebruiker alleen de naam en prijs van een product bewerken zonder dat andere productvelden verloren gaan.
Afbeelding 6: Met de interface kunt u alleen de naam en prijs van het product bewerken (klik om de volledige afbeelding weer te geven)
Opmerking
Zoals besproken in de vorige zelfstudie, is het van cruciaal belang dat de weergavestatus van GridView is ingeschakeld (het standaardgedrag). Als u de EnableViewState-eigenschap van GridView instelt op false, loopt u het risico dat gelijktijdige gebruikers onbedoeld records verwijderen of bewerken.
DeUnitPriceopmaak verbeteren
Hoewel het GridView-voorbeeld in afbeelding 6 werkt, wordt het UnitPrice veld helemaal niet opgemaakt, wat resulteert in een prijsweergave die geen valutasymbolen bevat en vier decimalen heeft. Als u een valutaopmaak wilt toepassen voor de niet-bewerkbare rijen, stelt u de eigenschap van het BoundField UnitPrice in op DataFormatString en de bijbehorende eigenschap {0:c} op HtmlEncode.
Afbeelding 7: Stel de UnitPrice's DataFormatString en HtmlEncode eigenschappen dienovereenkomstig in (klik om de volledige afbeelding weer te geven)
Met deze wijziging maken de niet-bewerkbare rijen de prijs op als valuta; de bewerkte rij geeft echter nog steeds de waarde weer zonder het valutasymbool en met vier decimalen.
Afbeelding 8: Niet-bewerkbare rijen zijn nu opgemaakt als valutawaarden (klik hier om de volledige afbeelding weer te geven)
De opmaakinstructies die in de DataFormatString eigenschap zijn opgegeven, kunnen worden toegepast op de bewerkingsinterface door de eigenschap BoundField's ApplyFormatInEditMode in te stellen op true (de standaard is false). Neem even de tijd om deze eigenschap in te stellen op true.
Afbeelding 9: Stel de UnitPrice eigenschap BoundField ApplyFormatInEditMode in op true (klik om de afbeelding op volledige grootte weer te geven)
Met deze wijziging wordt de waarde van de UnitPrice weergegeven in de bewerkte rij ook opgemaakt als een valuta.
Afbeelding 10: De waarde van UnitPrice de bewerkte rij is nu opgemaakt als valuta (klik om de afbeelding op volledige grootte weer te geven)
Het bijwerken van een product met het valutasymbool in het tekstvak, zoals $ 19,00, genereert echter een FormatException. Wanneer gridView probeert de door de gebruiker opgegeven waarden toe te wijzen aan de verzameling ObjectDataSource UpdateParameters , kan de UnitPrice tekenreeks $19,00 niet worden geconverteerd naar de decimal vereiste door de parameter (zie afbeelding 11). Om dit te verhelpen, kunnen we een gebeurtenishandler maken voor het RowUpdating-evenement van de GridView en de door de gebruiker gespecificeerde UnitPrice parseren als een valutanotatie decimal.
De gebeurtenis van GridView RowUpdating accepteert als de tweede parameter een object van het type GridViewUpdateEventArgs, dat een NewValues woordenlijst bevat als een van de eigenschappen die de door de gebruiker opgegeven waarden bevat die gereed zijn voor toewijzing aan de verzameling ObjectDataSource UpdateParameters . We kunnen de bestaande UnitPrice waarde in de NewValues verzameling overschrijven met een decimale waarde die wordt geparseerd met behulp van het valutaformaat met de volgende regels van code in de RowUpdating gebeurtenis-handler.
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);
}
Als de gebruiker een UnitPrice waarde (zoals $19,00) heeft opgegeven, wordt deze waarde overschreven met de decimale waarde die wordt berekend door Decimal.Parse, waarbij de waarde als valuta wordt geparseerd. Hiermee wordt het decimaalteken correct geparseerd in het geval van valutasymbolen, komma's, decimalen, enzovoort, en wordt de opsomming NumberStyles gebruikt in de naamruimte System.Globalization .
In afbeelding 11 ziet u zowel het probleem dat wordt veroorzaakt door valutasymbolen in de door de gebruiker opgegeven UnitPrice, samen met de manier waarop de gebeurtenis-handler van RowUpdating GridView kan worden gebruikt om dergelijke invoer correct te parseren.
Afbeelding 11: De waarde van UnitPrice de bewerkte rij is nu opgemaakt als valuta (klik hier om de volledige afbeelding weer te geven)
Stap 2: VerbiedenNULL UnitPrices
Hoewel de database is geconfigureerd om NULL waarden in de Products kolom van de UnitPrice tabel toe te staan, willen we mogelijk voorkomen dat gebruikers die deze specifieke pagina bezoeken een NULLUnitPrice waarde opgeven. Dat wil zeggen, als een gebruiker bij het bewerken van een productrij geen waarde invoert in UnitPrice, willen we in plaats van de resultaten in de database op te slaan, een bericht tonen dat gebruikers informeert dat op deze pagina bewerkte producten een opgegeven prijs moeten hebben.
Het GridViewUpdateEventArgs object dat wordt doorgegeven aan de gebeurtenis-handler van RowUpdating GridView bevat een Cancel eigenschap die, indien ingesteld true, het updateproces beëindigt. Laten we de RowUpdating gebeurtenisafhandelaar uitbreiden om e.Cancel in te stellen op true en een bericht weer te geven dat uitlegt waarom, als de UnitPrice waarde in de NewValues verzameling null is.
Begin met het toevoegen van een labelweb besturingselement aan de pagina met de naam MustProvideUnitPriceMessage. Dit labelcontrole wordt weergegeven als de gebruiker geen UnitPrice-waarde opgeeft bij het bijwerken van een product. Stel de eigenschap van het label Text in op 'U moet een prijs voor het product opgeven'. Ik heb ook een nieuwe CSS-klasse gemaakt in Styles.css met de volgende definitie Warning:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Stel ten slotte CssClass de eigenschap van het label in op Warning. Op dit moment moet de ontwerpfunctie het waarschuwingsbericht in een rood, vet, cursief, extra grote tekengrootte boven de GridView weergeven, zoals wordt weergegeven in afbeelding 12.
Afbeelding 12: Er is een label toegevoegd boven de Rasterweergave (klik om de afbeelding op volledige grootte weer te geven)
Dit label moet standaard worden verborgen, dus stel de eigenschap Visible in op false in de Page_Load gebeurtenisafhandelaar.
protected void Page_Load(object sender, EventArgs e)
{
MustProvideUnitPriceMessage.Visible = false;
}
Als de gebruiker een product probeert bij te werken zonder de UnitPriceop te geven, willen we de update annuleren en het waarschuwingslabel weergeven. Vergroot de gebeurtenis-handler van RowUpdating GridView als volgt:
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;
}
}
Als een gebruiker probeert een product op te slaan zonder een prijs op te geven, wordt de update geannuleerd en wordt er een nuttig bericht weergegeven. Hoewel de database (en bedrijfslogica) NULLUnitPrice toestaat, ondersteunt deze specifieke ASP.NET-pagina dat niet.
Afbeelding 13: Een gebruiker kan niet leeg laten UnitPrice (klik om de afbeelding op volledige grootte weer te geven)
Tot nu toe hebben we gezien hoe we de gebeurtenis van GridView RowUpdating kunnen gebruiken om programmatisch de parameterwaarden te wijzigen die zijn toegewezen aan de verzameling van UpdateParameters ObjectDataSource en hoe het updateproces helemaal kan worden geannuleerd. Deze concepten worden overgedragen naar de besturingselementen DetailsView en FormView en zijn ook van toepassing op invoegen en verwijderen.
Deze taken kunnen ook worden uitgevoerd op het niveau van de ObjectDataSource via eventhandlers voor de Inserting, Updating, en Deleting-gebeurtenissen. Deze gebeurtenissen worden geactiveerd voordat de bijbehorende methode van het onderliggende object wordt aangeroepen en bieden een laatste kans om de verzameling invoerparameters te wijzigen of de bewerking geheel te annuleren. De gebeurtenis-handlers voor deze drie gebeurtenissen worden doorgegeven aan een object van het type ObjectDataSourceMethodEventArgs met twee eigenschappen:
-
Annuleren, wat, indien ingesteld
trueop, annuleert de bewerking die wordt uitgevoerd -
InputParameters, de verzameling
InsertParameters,UpdateParameters, ofDeleteParameters, afhankelijk van of de gebeurtenis-handler voor deInserting,Updating, ofDeletinggebeurtenis is
Ter illustratie van het werken met de parameterwaarden op ObjectDataSource-niveau, gaan we een DetailsView opnemen op onze pagina waarmee de gebruikers een nieuw product kunnen toevoegen. Deze DetailsView wordt gebruikt om een interface te bieden voor het snel toevoegen van een nieuw product aan de database. Als u een consistente gebruikersinterface wilt behouden bij het toevoegen van een nieuw product, kunnen gebruikers alleen waarden voor de ProductName en UnitPrice velden invoeren. Standaard worden de waarden die niet zijn opgegeven in de invoeginterface van DetailsView ingesteld op een NULL databasewaarde. We kunnen echter de gebeurtenis van ObjectDataSource Inserting gebruiken om verschillende standaardwaarden in te voeren, zoals we binnenkort zullen zien.
Stap 3: een interface bieden voor het toevoegen van nieuwe producten
Sleep een DetailsView van de Werkset naar de Ontwerper boven de GridView, wis zijn eigenschappen Height en Width, en koppel deze aan de ObjectDataSource die al aanwezig is op de pagina. Hiermee voegt u een BoundField- of CheckBoxField toe voor elk van de velden van het product. Omdat we deze DetailsView willen gebruiken om nieuwe producten toe te voegen, moeten we de optie Invoegen inschakelen vanuit de infotag controleren; Er is echter geen dergelijke optie omdat de methode van ObjectDataSource Insert() niet is toegewezen aan een methode in de ProductsBLL klasse (onthoud dat we deze toewijzing instellen op (Geen) bij het configureren van de gegevensbron zie afbeelding 3.
Als u ObjectDataSource wilt configureren, selecteert u de koppeling Gegevensbron configureren vanuit de infotag en start u de wizard. In het eerste scherm kunt u het onderliggende object wijzigen waaraan de ObjectDataSource is gebonden; laat het ingesteld op ProductsBLL. In het volgende scherm worden de toewijzingen van de methoden van ObjectDataSource weergegeven aan de onderliggende objecten. Hoewel we expliciet hebben aangegeven dat de Insert() en Delete() methoden niet aan methoden moeten worden toegewezen, ziet u dat er een toewijzing is als u naar de tabbladen INVOEGEN en VERWIJDEREN gaat. Dit komt doordat de ProductsBLL's AddProduct en DeleteProduct methoden het DataObjectMethodAttribute kenmerk gebruiken om aan te geven dat ze de standaardmethoden zijn voor Insert() respectievelijk Delete(). Daarom selecteert de wizard ObjectDataSource deze telkens wanneer u de wizard uitvoert, tenzij er expliciet een andere waarde is opgegeven.
Laat de Insert() methode wijzen naar de AddProduct methode, maar stel de vervolgkeuzelijst van het tabblad DELETE opnieuw in op (Geen).
Afbeelding 14: Stel de Drop-Down lijst van het tabblad INVOEGEN in op de AddProduct methode (klik om de afbeelding op volledige grootte weer te geven)
Afbeelding 15: De Drop-Down lijst van het tabblad DELETE instellen op (Geen) (Klik om de afbeelding op volledige grootte weer te geven)
Nadat u deze wijzigingen hebt aangebracht, wordt de declaratieve syntaxis van ObjectDataSource uitgebreid met een InsertParameters verzameling, zoals hieronder wordt weergegeven:
<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>
Het opnieuw uitvoeren van de wizard heeft de OldValuesParameterFormatString eigenschap weer toegevoegd. Neem even de tijd om deze eigenschap te wissen door deze in te stellen op de standaardwaarde ({0}) of helemaal te verwijderen uit de declaratieve syntaxis.
Nu ObjectDataSource invoegmogelijkheden biedt, bevat de infotag van DetailsView nu het selectievakje Invoegen inschakelen; ga terug naar de ontwerpfunctie en schakel deze optie in. Vervolgens minimaliseer de DetailsView zodat deze slechts twee BoundFields - ProductName en UnitPrice - en het CommandField bevat. Op dit moment moet de declaratieve syntaxis van de DetailsView er als volgt uitzien:
<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>
In afbeelding 16 ziet u deze pagina wanneer deze op dit moment via een browser wordt bekeken. Zoals u ziet, vermeldt de DetailsView de naam en prijs van het eerste product (Chai). Wat we willen, is echter een invoeginterface waarmee de gebruiker snel een nieuw product aan de database kan toevoegen.
Afbeelding 16: De DetailsView wordt momenteel weergegeven in Read-Only modus (klik om de afbeelding op volledige grootte weer te geven)
Als u de DetailsView wilt weergeven in de invoegmodus, moet u de DefaultMode eigenschap instellen op Inserting. Hiermee wordt de DetailsView weergegeven in de invoegmodus wanneer deze voor het eerst wordt bezocht en blijft deze daar na het invoegen van een nieuwe record. Zoals in afbeelding 17 wordt weergegeven, biedt een dergelijke DetailsView een snelle interface voor het toevoegen van een nieuwe record.
Afbeelding 17: De DetailsView biedt een interface voor het snel toevoegen van een nieuw product (klik om een volledige afbeelding weer te geven)
Wanneer de gebruiker een productnaam en -prijs invoert (zoals 'Acme Water' en 1.99, zoals in afbeelding 17) en op Invoegen klikt, wordt een postback achtervolgd en begint de invoegwerkstroom, waarbij een nieuwe productrecord wordt toegevoegd aan de database. De DetailView onderhoudt de invoeginterface en de GridView wordt automatisch hersteld naar de gegevensbron om het nieuwe product op te nemen, zoals wordt weergegeven in afbeelding 18.
Afbeelding 18: Het product "Acme Water" is toegevoegd aan de database
Hoewel rasterweergave in afbeelding 18 deze niet weergeeft, worden aan de productvelden die ontbreken in de DetailsView-interfaceCategoryIDSupplierID, QuantityPerUnitenzovoort databasewaarden toegewezenNULL. U kunt dit zien door de volgende stappen uit te voeren:
- Ga naar Server Explorer in Visual Studio
- Het
NORTHWND.MDFdatabaseknooppunt uitbreiden - Klik met de rechtermuisknop op het
Productsdatabasetabelknooppunt - Selecteer Tabelgegevens Weergeven
Hiermee worden alle records in de Products tabel weergegeven. Zoals in afbeelding 19 wordt weergegeven, bevatten alle kolommen van ons nieuwe product behalve ProductID, ProductNameen UnitPrice waarden NULL .
Afbeelding 19: De productvelden die niet zijn opgegeven in de DetailsView, zijn toegewezen NULL waarden (klik hier om de volledige afbeelding weer te geven)
We willen mogelijk een andere standaardwaarde dan NULL voor een of meer van deze kolomwaarden opgeven, omdat NULL dit niet de beste standaardoptie is of omdat de databasekolom zelf niet toestaat NULL . Hiervoor kunnen we programmatisch de waarden van de parameters van de verzameling detailsweergave InputParameters instellen. Deze toewijzing kan worden uitgevoerd in de eventhandler voor de ItemInserting gebeurtenis van de DetailsView of de Inserting gebeurtenis van de ObjectDataSource. Aangezien we al hebben gekeken naar het gebruik van de pre- en post-level gebeurtenissen op het niveau van het databesturingselement, laten we dit keer de gebeurtenissen van ObjectDataSource verkennen.
Stap 4: Waarden toewijzen aan deCategoryIDenSupplierIDparameters
Voor deze zelfstudie stellen we ons voor dat aan onze toepassing bij het toevoegen van een nieuw product via deze interface een CategoryID en SupplierID waarde van 1 moet worden toegewezen. Zoals eerder vermeld, heeft de ObjectDataSource een paar gebeurtenissen vooraf en na het niveau die worden geactiveerd tijdens het wijzigingsproces van de gegevens. Wanneer zijn Insert() methode wordt aangeroepen, genereert de ObjectDataSource eerst zijn Inserting gebeurtenis, roept vervolgens de methode aan waaraan zijn Insert() methode is toegewezen, en genereert ten slotte de Inserted gebeurtenis. De Inserting gebeurtenis-handler biedt ons een laatste mogelijkheid om de invoerparameters aan te passen of de bewerking te annuleren.
Opmerking
In een echte toepassing wilt u de gebruiker waarschijnlijk de categorie en leverancier laten opgeven of deze waarde voor hen kiezen op basis van bepaalde criteria of bedrijfslogica (in plaats van blind een id van 1 te selecteren). In het voorbeeld ziet u hoe u programmatisch de waarde van een invoerparameter kunt instellen op basis van de gebeurtenis vóór het niveau van ObjectDataSource.
Neem even de tijd om een eventhandler te maken voor de Inserting gebeurtenis van de ObjectDataSource. U ziet dat de tweede invoerparameter van de gebeurtenis-handler een object van het type ObjectDataSourceMethodEventArgsis, dat een eigenschap heeft voor toegang tot de parametersverzameling (InputParameters) en een eigenschap om de bewerking (Cancel) te annuleren.
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
}
Op dit moment bevat de InputParameters eigenschap de verzameling ObjectDataSource InsertParameters met de waarden die zijn toegewezen vanuit de DetailsView. Als u de waarde van een van deze parameters wilt wijzigen, gebruikt u gewoon: e.InputParameters["paramName"] = value. Om de waarden van CategoryID en SupplierID op 1 in te stellen, past u de Inserting-gebeurtenishandler aan zoals hieronder weergegeven:
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["CategoryID"] = 1;
e.InputParameters["SupplierID"] = 1;
}
Deze keer wanneer u een nieuw product toevoegt (zoals Acme Soda), worden de CategoryID kolommen SupplierID van het nieuwe product ingesteld op 1 (zie afbeelding 20).
Afbeelding 20: Nieuwe producten hebben nu hun CategoryID en SupplierID waarden ingesteld op 1 (klik om de afbeelding op volledige grootte weer te geven)
Samenvatting
Tijdens het bewerken, invoegen en verwijderen tijdens het proces doorlopen zowel het gegevenswebbesturingselement als de ObjectDataSource een aantal pre-niveau en post-niveau gebeurtenissen. In deze zelfstudie hebben we de gebeurtenissen op het niveau vooraf onderzocht en gezien hoe u deze kunt gebruiken om de invoerparameters aan te passen of de bewerking voor het wijzigen van gegevens helemaal te annuleren, zowel vanuit het gegevenswebbesturingselement als de gebeurtenissen van ObjectDataSource. In de volgende handleiding kijken we naar het maken en gebruiken van gebeurtenis-handlers voor gebeurtenissen op postniveau.
Veel plezier met programmeren!
Over de auteur
Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.
Speciale dank aan
Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdreviewers voor deze handleiding waren Jackie Goor en Liz Shulok. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.