Sdílet prostřednictvím


Zkoumání událostí spojených s vložením, aktualizací a odstraněním (C#)

Scott Mitchell

Stáhnout PDF

V tomto kurzu prozkoumáme události, ke kterým dochází před, během a po operaci vložení, aktualizace nebo odstranění webového ovládacího prvku ASP.NET dat. Uvidíme také, jak přizpůsobit rozhraní pro úpravy tak, aby se aktualizovala jenom podmnožina polí produktů.

Úvod

Při použití integrovaných funkcí pro vkládání, úpravy nebo odstraňování ovládacích prvků GridView, DetailsView nebo FormView se různé kroky objeví, když koncový uživatel dokončí proces přidání nového záznamu nebo aktualizace nebo odstranění existujícího záznamu. Jak jsme probírali v předchozím kurzu, při úpravě řádku v objektu GridView se tlačítko Upravit nahradí tlačítky Update a Cancel a BoundField se změní na textová pole. Po aktualizaci dat koncovým uživatelem a kliknutí na Aktualizovat se při zpětném odeslání provede následující kroky:

  1. Objekt GridView naplní své objekty ObjectDataSource UpdateParameters jedinečnými identifikačními poli upraveného záznamu (prostřednictvím DataKeyNames vlastnosti) spolu s hodnotami zadanými uživatelem.
  2. Objekt GridView vyvolá svou metodu Update() ObjectDataSource, která zase vyvolá příslušnou metodu v podkladovém objektu (ProductsDAL.UpdateProductv našem předchozím kurzu).
  3. Podkladová data, která teď zahrnují aktualizované změny, se přecházejí do zobrazení GridView.

Během této posloupnosti kroků se aktivuje řada událostí, které nám umožní vytvořit obslužné rutiny událostí pro přidání vlastní logiky tam, kde je to potřeba. Například před krokem 1 se aktivuje událost GridView RowUpdating . V tuto chvíli můžeme žádost o aktualizaci zrušit, pokud dojde k chybě ověření. Update() Při vyvolání metody se aktivuje událost ObjectDataSourceUpdating, která poskytuje příležitost přidat nebo přizpůsobit hodnoty libovolného objektu UpdateParameters. Po dokončení provádění metody podkladového objektu ObjectDataSource ObjectDataSource Updated je vyvolána událost. Obslužná rutina události může Updated kontrolovat podrobnosti o operaci aktualizace, například kolik řádků bylo ovlivněno a jestli nedošlo k výjimce. Nakonec se po kroku 2 aktivuje událost objektu GridView RowUpdated . Obslužná rutina události pro tuto událost může prozkoumat další informace o právě provedené operaci aktualizace.

Obrázek 1 znázorňuje tuto řadu událostí a kroků při aktualizaci objektu GridView. Model události na obrázku 1 není jedinečný pro aktualizaci pomocí objektu GridView. Vložením, aktualizací nebo odstraněním dat z objektu GridView, DetailsView nebo FormView se vytvoří stejná posloupnost událostí před a po úrovni pro webový ovládací prvek dat a objectDataSource.

Série událostí před a po spuštění při aktualizaci dat v gridview

Obrázek 1: Řada událostí před a po spuštění při aktualizaci dat v GridView (kliknutím zobrazíte obrázek v plné velikosti)

V tomto kurzu prozkoumáme použití těchto událostí k rozšíření integrovaných možností vkládání, aktualizace a odstraňování webových ovládacích prvků ASP.NET dat. Uvidíme také, jak přizpůsobit rozhraní pro úpravy tak, aby se aktualizovala jenom podmnožina polí produktů.

Krok 1: Aktualizace polí aUnitPriceproduktůProductName

V rozhraních pro úpravy z předchozího kurzu bylo nutné zahrnout všechna pole produktů, která nebyla určena jen pro čtení. Kdybychom například při aktualizaci dat odebrali pole z ovládacího prvku GridView QuantityPerUnit , ovládací prvek Data Web nenastavil hodnotu ObjectDataSource QuantityPerUnitUpdateParameters . ObjectDataSource by pak předal null hodnotu do UpdateProduct metody BLL (Business Logic Layer), která by změnila sloupec upraveného databázového QuantityPerUnit záznamu NULL na hodnotu. Podobně platí, že pokud je z rozhraní pro úpravy odebráno požadované pole, například ProductName, aktualizace selže s výjimkou Sloupec ProductName nepovoluje hodnoty null. Důvodem tohoto chování bylo to, že ObjectDataSource byl nakonfigurován tak, aby volal metodu ProductsBLL třídy UpdateProduct , která očekávala vstupní parametr pro každé pole produktu. Kolekce ObjectDataSource UpdateParameters proto obsahovala parametr pro každý vstupní parametr metody.

Pokud chceme poskytnout datový webový ovládací prvek, který umožňuje koncovému uživateli aktualizovat pouze podmnožinu polí, musíme buď programově nastavit chybějící UpdateParameters hodnoty v obslužné rutině události ObjectDataSource Updating , nebo vytvořit a volat metodu BLL, která očekává pouze podmnožinu polí. Pojďme se podívat na tento druhý přístup.

Konkrétně vytvoříme stránku, která v upravitelném zobrazení GridView zobrazuje pouze ProductName pole a UnitPrice . Toto rozhraní pro úpravy objektu GridView umožní uživateli aktualizovat pouze dvě zobrazená pole a ProductNameUnitPrice. Vzhledem k tomu, že toto rozhraní pro úpravy poskytuje pouze podmnožinu polí produktu, musíme buď vytvořit ObjectDataSource, který používá existující metodu BLL UpdateProduct a má chybějící hodnoty polí produktu nastavené programově ve své Updating obslužné rutině události, nebo potřebujeme vytvořit novou metodu BLL, která očekává pouze podmnožinu polí definovanou v GridView. Pro účely tohoto kurzu použijeme druhou možnost a vytvoříme přetížení UpdateProduct metody, která přijímá pouze tři vstupní parametry: productName, unitPricea 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;
}

Stejně jako u původní UpdateProduct metody toto přetížení začíná kontrolou, zda databáze nemá produkt se zadaným ProductIDparametrem . Pokud ne, vrátí hodnotu false, což znamená, že žádost o aktualizaci informací o produktu selhala. V opačném případě aktualizuje pole a existujícího záznamu ProductName produktu odpovídajícím způsobem a potvrdí aktualizaci voláním metody TableAdapter Update() a předáním ProductsRow instance.UnitPrice

S tímto přidáním do naší ProductsBLL třídy jsme připraveni vytvořit zjednodušené rozhraní GridView. DataModificationEvents.aspx Otevřete ve EditInsertDelete složce a na stránku přidejte GridView. Vytvořte nový ObjektDataSource a nakonfigurujte ho ProductsBLL tak, aby používal třídu s Select() mapováním metody na GetProducts a mapování metody Update() na UpdateProduct přetížení, které přijímá pouze productNamevstupní parametry , unitPricea productID . Obrázek 2 znázorňuje průvodce vytvořením zdroje dat při mapování metody ObjectDataSource Update() na ProductsBLL přetížení nové UpdateProduct metody třídy.

Namapujte metodu Update() objectDataSource na new UpdateProduct přetížení.

Obrázek 2: Mapování metody ObjectDataSource Update() na new UpdateProduct přetížení (kliknutím zobrazíte obrázek v plné velikosti)

Vzhledem k tomu, že náš příklad bude zpočátku potřebovat jenom možnost upravovat data, ale ne vkládat nebo odstraňovat záznamy, chvíli se ujistěte, že metody a Delete() ObjectDataSource Insert() by neměly být mapovány na žádnou z ProductsBLL metod třídy tak, že přejdete na karty INSERT a DELETE a z rozevíracího seznamu zvolíte (None).

V seznamu Drop-Down zvolte (Žádný) pro karty VLOŽENÍ a ODSTRANIT.

Obrázek 3: V seznamu Drop-Down zvolte (Žádné) pro karty VLOŽENÍ a ODSTRANIT (kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení tohoto průvodce zaškrtněte políčko Povolit úpravy z inteligentní značky GridView.

Po dokončení průvodce vytvořením zdroje dat a vazby, která se gridView, Visual Studio vytvořil deklarativní syntaxi pro oba ovládací prvky. Přejděte do zobrazení Zdroj a zkontrolujte deklarativní kód ObjectDataSource, který je zobrazený níže:

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

Vzhledem k tomu, že neexistují žádné mapování pro objectDataSource Insert()Delete() a metody, neexistují žádné InsertParameters oddíly nebo DeleteParameters . Vzhledem k Update() tomu, že metoda je mapována na UpdateProduct přetížení metody, které přijímá pouze tři vstupní parametry, UpdateParameters má oddíl pouze tři Parameter instance.

Všimněte si, že vlastnost ObjectDataSource OldValuesParameterFormatString je nastavená na original_{0}. Tato vlastnost je automaticky nastavena sadou Visual Studio při použití průvodce Konfigurovat zdroj dat. Vzhledem k tomu, že naše metody BLL neočekávají předání původní ProductID hodnoty, odeberte toto přiřazení vlastnosti úplně z deklarativní syntaxe ObjectDataSource.

Poznámka

Pokud jednoduše vymažete OldValuesParameterFormatString hodnotu vlastnosti z okno Vlastnosti v návrhovém zobrazení, vlastnost bude stále existovat v deklarativní syntaxi, ale bude nastavena na prázdný řetězec. Buď úplně odeberte vlastnost z deklarativní syntaxe, nebo v okno Vlastnosti nastavte hodnotu na výchozí {0}hodnotu .

Zatímco ObjectDataSource má UpdateParameters pouze pro název produktu, cenu a ID, Visual Studio přidal BoundField nebo CheckBoxField do GridView pro každé z polí produktu.

Objekt GridView obsahuje BoundField nebo CheckBoxField pro každé pole produktu.

Obrázek 4: Objekt GridView obsahuje BoundField nebo CheckBoxField pro každé pole produktu (kliknutím zobrazíte obrázek v plné velikosti)

Když koncový uživatel upraví produkt a klikne na tlačítko Aktualizovat, GridView vytvoří výčet polí, která nebyla jen pro čtení. Potom nastaví hodnotu odpovídajícího parametru v kolekci ObjectDataSource UpdateParameters na hodnotu zadanou uživatelem. Pokud neexistuje odpovídající parametr, GridView přidá jeden do kolekce. Proto pokud náš GridView obsahuje BoundFields a CheckBoxFields pro všechna pole produktu, ObjectDataSource skončí vyvolá UpdateProduct přetížení, které přijímá všechny tyto parametry, navzdory skutečnosti, že deklarativní kód ObjectDataSource určuje pouze tři vstupní parametry (viz Obrázek 5). Podobně pokud existuje nějaká kombinace polí produktu, které nejsou jen pro čtení v GridView, která neodpovídá vstupním parametrům UpdateProduct pro přetížení, bude vyvolána výjimka při pokusu o aktualizaci.

Objekt GridView přidá parametry do kolekce UpdateParameters objektu ObjectDataSource.

Obrázek 5: Objekt GridView přidá parametry do kolekce ObjectDataSource UpdateParameters (kliknutím zobrazíte obrázek v plné velikosti)

Abychom zajistili, že ObjectDataSource vyvolá UpdateProduct přetížení, které přebírá pouze název produktu, cenu a ID, musíme omezit GridView na upravitelná pole pouze ProductName pro a UnitPrice. Toho lze dosáhnout odebráním ostatních boundfields a CheckBoxFields, nastavením vlastnosti těchto dalších polí ReadOnly na truehodnotu nebo určitou kombinací těchto dvou polí. Pro účely tohoto kurzu jednoduše odebereme všechna pole GridView kromě ProductName polí a UnitPrice BoundFields, po kterých bude deklarativní kód GridView vypadat takto:

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

I když UpdateProduct přetížení očekává tři vstupní parametry, máme pouze dvě BoundFields v našem GridView. Je to proto, že productID vstupní parametr je hodnota primárního klíče a předává se prostřednictvím hodnoty DataKeyNames vlastnosti pro upravený řádek.

Naše GridView, spolu s UpdateProduct přetížením, umožňuje uživateli upravit pouze název a cenu produktu, aniž by přišla o jakékoli jiné pole produktu.

Rozhraní umožňuje upravovat pouze název a cenu produktu.

Obrázek 6: Rozhraní umožňuje úpravu pouze názvu a ceny produktu (kliknutím zobrazíte obrázek v plné velikosti)

Poznámka

Jak je popsáno v předchozím kurzu, je velmi důležité, aby byl povolen stav zobrazení GridView (výchozí chování). Pokud nastavíte vlastnost falseGridView na EnableViewState hodnotu , riskujete, že souběžní uživatelé neúmyslně odstraní nebo upraví záznamy.

UnitPriceVylepšení formátování

I když příklad GridView zobrazený na obrázku 6 funguje, UnitPrice pole není vůbec formátováno, což vede k zobrazení ceny, která neobsahuje symboly měny a má čtyři desetinná místa. Pokud chcete použít formátování měny pro neupravitelné řádky, jednoduše nastavte UnitPrice vlastnost BoundField DataFormatString na {0:c} a její HtmlEncode vlastnost na false.

Nastavte vlastnosti DataFormatString a HtmlEncode hodnoty UnitPrice.

Obrázek 7: Odpovídající nastavení UnitPriceDataFormatString vlastností a HtmlEncode (kliknutím zobrazíte obrázek v plné velikosti)

S touto změnou, neupravitelné řádky formátovat cenu jako měnu; upravený řádek však stále zobrazuje hodnotu bez symbolu měny a se čtyřmi desetinnými místy.

Neupravitelné řádky jsou teď formátované jako hodnoty měny.

Obrázek 8: Neupravitelné řádky jsou teď formátované jako hodnoty měny (kliknutím zobrazíte obrázek v plné velikosti)

Pokyny k formátování zadané ve DataFormatString vlastnosti lze použít pro rozhraní pro úpravy nastavením vlastnosti BoundField ApplyFormatInEditMode na true hodnotu (výchozí hodnota je false). Nastavte tuto vlastnost na true.

Nastavte vlastnost ApplyFormatInEditMode unitPrice BoundField na hodnotu true.

Obrázek 9: Nastavení UnitPrice vlastnosti BoundField ApplyFormatInEditMode na true (Kliknutím zobrazíte obrázek v plné velikosti)

Po této změně se hodnota UnitPrice zobrazená v upraveném řádku naformátuje také jako měna.

Snímek obrazovky objektu GridView zobrazující hodnotu UnitPrice upraveného řádku formátovanou jako měna

Obrázek 10: Hodnota upraveného UnitPrice řádku je teď formátovaná jako měna (kliknutím zobrazíte obrázek v plné velikosti)

Aktualizace produktu se symbolem měny v textovém poli, jako je například $19,00, však vyvolá FormatExceptionchybu . Když se Objekt GridView pokusí přiřadit uživatelem zadané hodnoty do kolekce ObjectDataSource UpdateParameters , nemůže převést UnitPrice řetězec $19.00 na decimal požadovaný parametrem (viz obrázek 11). Abychom to mohli napravit, můžeme vytvořit obslužnou rutinu události pro událost GridView RowUpdating a nechat ji analyzovat uživatelem zadaný UnitPrice jako měnu formátovaný decimal.

Událost objektu GridView RowUpdating přijímá jako druhý parametr objekt typu GridViewUpdateEventArgs, který obsahuje NewValues slovník jako jednu z jeho vlastností, která uchovává uživatelem zadané hodnoty připravené k přiřazení k kolekci ObjectDataSource UpdateParameters . Existující UnitPrice hodnotu v NewValues kolekci můžeme přepsat desetinnou hodnotou parsovanou pomocí formátu měny pomocí následujících řádků kódu v obslužné rutině RowUpdating události:

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);
}

Pokud uživatel zadal UnitPrice hodnotu (například 19,00 Kč), tato hodnota se přepíše desetinnou hodnotou vypočítanou pomocí funkce Decimal.Parse a parsuje hodnotu jako měnu. Tím se správně parsuje desetinná čárka v případě symbolů měny, čárk, desetinných míst atd. a použije výčet NumberStyles v oboru názvů System.Globalization .

Obrázek 11 znázorňuje problém způsobený symboly měny v uživatelem zadaném UnitPriceobjektu a způsob použití obslužné rutiny události GridView RowUpdating ke správné analýze takového vstupu.

Diagram znázorňující, jak ObjectDataSource zpracovává pole UnitPrice a jak obslužná rutina události RowUpdate objektu GridView převede řetězec na desítkové číslo.

Obrázek 11: Hodnota upraveného UnitPrice řádku je teď formátovaná jako měna (kliknutím zobrazíte obrázek v plné velikosti)

Krok 2: ZákazNULL UnitPrices

I když je databáze nakonfigurovaná tak, aby umožňovala NULL hodnoty ve Products sloupci tabulky UnitPrice , můžeme chtít zabránit uživatelům, kteří navštíví tuto konkrétní stránku, v zadání NULLUnitPrice hodnoty. To znamená, že pokud uživatel nezadá UnitPrice hodnotu při úpravě řádku produktu, místo uložení výsledků do databáze chceme zobrazit zprávu informující uživatele, že na této stránce musí mít všechny upravené produkty určenou cenu.

Objekt GridViewUpdateEventArgs předaný do obslužné rutiny události GridView RowUpdating obsahuje Cancel vlastnost, která, pokud je nastavena na true, ukončí proces aktualizace. Pojďme rozšířit obslužnou rutinu RowUpdating události na true hodnotu e.Cancel a zobrazit zprávu vysvětlující, proč UnitPrice je nullhodnota v kolekci NewValues .

Začněte přidáním ovládacího prvku Label Web na stránku s názvem MustProvideUnitPriceMessage. Tento ovládací prvek Popisek se zobrazí, pokud se uživateli nepodaří zadat UnitPrice hodnotu při aktualizaci produktu. Nastavte vlastnost Label na Text "Musíte zadat cenu produktu". Vytvořil(a) jsem také novou třídu CSS s Styles.css názvem Warning s následující definicí:

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

Nakonec nastavte vlastnost Label CssClass na Warning. V tomto okamžiku by Designer měla zobrazit zprávu upozornění červenou, tučně kurzívou a mimořádně velkou velikostí písma nad objektem GridView, jak je znázorněno na obrázku 12.

Nad objekt GridView byl přidán popisek.

Obrázek 12: Nad Objekt GridView byl přidán popisek (kliknutím zobrazíte obrázek v plné velikosti)

Ve výchozím nastavení by měl být tento popisek skrytý, proto v obslužné rutině události nastavte jeho Visible vlastnost na falsePage_Load :

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

Pokud se uživatel pokusí aktualizovat produkt bez zadání UnitPrice, chceme aktualizaci zrušit a zobrazit popisek upozornění. Rozšiřte obslužnou rutinu RowUpdating události GridView následujícím způsobem:

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;
    }
}

Pokud se uživatel pokusí uložit produkt bez zadání ceny, aktualizace se zruší a zobrazí se užitečná zpráva. I když databáze (a obchodní logika) umožňuje NULLUnitPrice s, tato konkrétní ASP.NET stránka ne.

Uživatel nemůže ponechat jednotkovou cenu prázdnou.

Obrázek 13: Uživatel nemůže nechat UnitPrice prázdný (kliknutím zobrazíte obrázek v plné velikosti)

Zatím jsme viděli, jak pomocí události GridView RowUpdating programově změnit hodnoty parametrů přiřazené kolekci ObjectDataSource UpdateParameters a jak proces aktualizace úplně zrušit. Tyto koncepty se přenášejí do ovládacích prvků DetailsView a FormView a platí také pro vkládání a odstraňování.

Tyto úlohy lze také provádět na úrovni ObjectDataSource prostřednictvím obslužných rutin událostí pro jeho Insertingudálosti , Updatinga Deleting . Tyto události se aktivují před vyvoláním přidružené metody podkladového objektu a poskytují poslední příležitost změnit kolekci vstupních parametrů nebo přímo zrušit operaci. Obslužné rutiny událostí pro tyto tři události jsou předány objektu typu ObjectDataSourceMethodEventArgs , který má dvě vlastnosti zájmu:

  • Zrušit, což, pokud je nastaveno na true, zruší prováděnou operaci.
  • InputParameters, což je kolekce InsertParameters, UpdateParametersnebo DeleteParameters, v závislosti na tom, jestli je obslužná rutina události pro InsertingUpdating, nebo Deleting

Pro ilustraci práce s hodnotami parametrů na úrovni ObjectDataSource zahrňme na naši stránku DetailsView, které uživatelům umožní přidat nový produkt. Toto zobrazení DetailsView bude sloužit k poskytování rozhraní pro rychlé přidání nového produktu do databáze. Pokud chcete při přidávání nového produktu zachovat konzistentní uživatelské rozhraní, umožníme uživateli zadávat jenom hodnoty pro ProductName pole a UnitPrice . Ve výchozím nastavení se hodnoty, které nejsou zadané v rozhraní pro vkládání DetailsView, nastaví na NULL hodnotu databáze. Můžeme ale použít událost ObjectDataSource Inserting k vložení různých výchozích hodnot, jak uvidíme za chvíli.

Krok 3: Poskytnutí rozhraní pro přidání nových produktů

Přetáhněte DetailsView z panelu nástrojů na Designer nad GridView, vymažte jeho Height vlastnosti a Width a vytvořte vazbu k objektu ObjectDataSource již na stránce. Tím se pro všechna pole produktu přidá Pole BoundField nebo CheckBoxField. Vzhledem k tomu, že chceme použít tento DetailsView k přidání nových produktů, musíme zkontrolovat možnost Povolit vkládání z inteligentní značky; Taková možnost ale neexistuje, protože metoda ObjectDataSource Insert() není namapovaná na metodu ve ProductsBLL třídě (vzpomeňte si, že při konfiguraci zdroje dat jsme toto mapování nastavili na hodnotu (None) (Viz obrázek 3).

Pokud chcete nakonfigurovat ObjectDataSource, vyberte odkaz Konfigurovat zdroj dat z jeho inteligentní značky a spusťte průvodce. První obrazovka umožňuje změnit základní objekt ObjectDataSource je vázán na; Ponechte ji nastavenou na ProductsBLL. Další obrazovka obsahuje seznam mapování z metod ObjectDataSource na podkladové objekty. I když jsme výslovně uvedli, že Insert() metody a Delete() by neměly být mapovány na žádné metody, pokud přejdete na karty INSERT a DELETE, uvidíte, že je tam mapování. Je to proto, že ProductsBLLAddProduct metody a DeleteProduct používají DataObjectMethodAttribute atribut k označení, že se jedná o výchozí metody pro Insert() a Delete(), v uvedeném pořadí. Proto průvodce ObjectDataSource je vybere při každém spuštění průvodce, pokud není explicitně zadána jiná hodnota.

Ponechte metodu Insert() odkazující na metodu AddProduct , ale znovu nastavte rozevírací seznam karty DELETE na hodnotu (Žádné).

Nastavte seznam Drop-Down karty INSERT na metodu AddProduct.

Obrázek 14: Nastavení seznamu Drop-Down karty VLOŽENÍ na metodu AddProduct (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte seznam Drop-Down karty DELETE na hodnotu (Žádné).

Obrázek 15: Nastavte seznam Drop-Down karty DELETE na (Žádný) (Kliknutím zobrazíte obrázek v plné velikosti)

Po provedení těchto změn se deklarativní syntaxe ObjectDataSource rozbalí tak, aby zahrnovala kolekci InsertParameters , jak je znázorněno níže:

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

Opakováním průvodce se vlastnost přidala OldValuesParameterFormatString zpět. Chvíli trvá, než tuto vlastnost vymažete tak, že ji nastavíte na výchozí hodnotu ({0}) nebo ji úplně odeberete z deklarativní syntaxe.

S ObjectDataSource poskytovat možnosti vkládání, DetailsView inteligentní značka bude nyní obsahovat povolit vkládání zaškrtávací políčko; vraťte se do Designer a zaškrtněte tuto možnost. Dále parefinujte DetailsView tak, aby měl pouze dvě BoundFields - ProductName a UnitPrice - a CommandField. V tomto okamžiku by deklarativní syntaxe DetailsView měla vypadat takto:

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

Obrázek 16 ukazuje tuto stránku při zobrazení v tomto okamžiku v prohlížeči. Jak vidíte, DetailsView uvádí název a cenu prvního produktu (Chai). Chceme ale rozhraní pro vkládání, které uživateli umožní rychle přidat nový produkt do databáze.

Zobrazení DetailsView se aktuálně vykresluje v režimu Read-Only.

Obrázek 16: Zobrazení DetailsView je aktuálně vykreslené v režimu Read-Only (kliknutím zobrazíte obrázek v plné velikosti)

Aby bylo možné zobrazit DetailsView v režimu vkládání, musíme vlastnost nastavit DefaultMode na Inserting. Tím se zobrazení DetailsView při první návštěvě vykreslí v režimu vložení a po vložení nového záznamu ho tam ponechá. Jak ukazuje obrázek 17, takové DetailsView poskytuje rychlé rozhraní pro přidání nového záznamu.

DetailsView poskytuje rozhraní pro rychlé přidání nového produktu

Obrázek 17: DetailsView poskytuje rozhraní pro rychlé přidání nového produktu (kliknutím zobrazíte obrázek v plné velikosti)

Když uživatel zadá název produktu a cenu (například "Acme Water" a 1.99, jako na obrázku 17) a klikne na Vložit, následuje postback a spustí se pracovní postup vložení, který vyvrcholí tím, že se do databáze přidá nový záznam o produktu. DetailsView udržuje své vložené rozhraní a GridView se automaticky odskočí do svého zdroje dat, aby zahrnoval nový produkt, jak je znázorněno na obrázku 18.

Produkt

Obrázek 18: Produkt "Acme Water" byl přidán do databáze

Zatímco GridView na obrázku 18 to nezobrazuje, pole produktů chybějící z rozhraní CategoryIDDetailsView , SupplierID, QuantityPerUnita tak dále jsou přiřazené NULL hodnoty databáze. Můžete to vidět provedením následujících kroků:

  1. Přejděte do Průzkumníka serveru v sadě Visual Studio.
  2. Rozbalení databázového NORTHWND.MDF uzlu
  3. Klikněte pravým tlačítkem na uzel tabulky databáze.Products
  4. Vyberte Zobrazit data tabulky.

Zobrazí se seznam všech záznamů v tabulce Products . Jak ukazuje obrázek 19, všechny sloupce nového produktu kromě ProductID, ProductNamea UnitPrice mají NULL hodnoty.

Pole produktů nezadá v zobrazení DetailsView jsou přiřazené hodnoty NULL.

Obrázek 19: Pole produktů nezadá v zobrazení DetailsView jsou přiřazené NULL hodnoty (kliknutím zobrazíte obrázek v plné velikosti)

Můžeme chtít zadat jinou výchozí hodnotu než NULL pro jednu nebo více hodnot těchto sloupců, a to buď proto, že NULL to není nejlepší výchozí možnost, nebo proto, že samotný sloupec databáze tyto hodnoty neumožňuje NULL . K tomu můžeme programově nastavit hodnoty parametrů kolekce DetailsView InputParameters . Toto přiřazení lze provést buď v obslužné rutině události DetailsView ItemInserting nebo v události ObjectDataSource Inserting . Vzhledem k tomu, že jsme se už podívali na použití událostí před a po úrovni na úrovni datového ovládacího prvku Web, pojďme tentokrát prozkoumat události ObjectDataSource.

Krok 4: Přiřazení hodnot k parametrůmCategoryIDaSupplierID

Pro účely tohoto kurzu si představme, že pro naši aplikaci by při přidávání nového produktu prostřednictvím tohoto rozhraní měla být přiřazena CategoryID hodnota a SupplierID 1. Jak už bylo zmíněno dříve, ObjectDataSource má dvojici událostí před a po úrovni, které se aktivují během procesu úpravy dat. Při vyvolání metody Insert() ObjectDataSource nejprve vyvolá svou Inserting událost, pak zavolá metodu, na kterou byla její Insert() metoda namapována, a nakonec vyvolá Inserted událost. Obslužná rutina Inserting události nám poskytuje poslední příležitost k úpravě vstupních parametrů nebo k okamžitému zrušení operace.

Poznámka

V reálné aplikaci byste pravděpodobně chtěli, aby uživatel zadal kategorii a dodavatele, nebo tuto hodnotu vybral na základě určitých kritérií nebo obchodní logiky (místo slepého výběru ID čísla 1). Bez ohledu na to příklad ukazuje, jak programově nastavit hodnotu vstupního parametru z události před úrovní ObjectDataSource.

Chvíli si vytvořte obslužnou rutinu události ObjectDataSource Inserting události. Všimněte si, že druhý vstupní parametr obslužné rutiny události je objekt typu ObjectDataSourceMethodEventArgs, který má vlastnost pro přístup ke kolekci parametrů (InputParameters) a vlastnost pro zrušení operace (Cancel).

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{

}

V tomto okamžiku InputParameters vlastnost obsahuje ObjectDataSource InsertParameters kolekce s hodnotami přiřazenými z DetailsView. Pokud chcete změnit hodnotu jednoho z těchto parametrů, jednoduše použijte: e.InputParameters["paramName"] = value. Proto pokud chcete nastavit CategoryID hodnoty a SupplierID na hodnotu 1, upravte obslužnou rutinu Inserting události tak, aby vypadala takto:

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

Tentokrát při přidávání nového produktu (například Acme Soda) CategoryID jsou sloupce a SupplierID nového produktu nastaveny na 1 (viz obrázek 20).

Nové produkty teď mají hodnoty CategoryID a SupplierID nastavené na 1.

Obrázek 20: Nové produkty teď mají hodnoty CategoryID a SupplierID nastavené na 1 (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

Během procesu úprav, vkládání a odstraňování prochází ovládací prvek Data Web i ObjectDataSource řadou událostí před a po úrovni. V tomto kurzu jsme prozkoumali události před úrovní a zjistili jsme, jak je použít k přizpůsobení vstupních parametrů nebo k úplnému zrušení operace úpravy dat jak z ovládacího prvku data web, tak z událostí ObjectDataSource. V dalším kurzu se podíváme na vytváření a používání obslužných rutin událostí pro události po úrovni.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty tohoto kurzu byli Jackie Goor a Liz Shulok. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .