Freigeben über


Überprüfen von Ereignissen im Zusammenhang mit Vorgängen zum Einfügen, Aktualisieren und Löschen (C#)

von Scott Mitchell

PDF herunterladen

In diesem Lernprogramm untersuchen wir die Verwendung der Ereignisse, die vor, während und nach einem Einfüge-, Aktualisierungs- oder Löschvorgang eines ASP.NET Datenwebsteuerelements auftreten. Außerdem erfahren Sie, wie Sie die Bearbeitungsschnittstelle so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.

Einführung

Bei Verwendung der integrierten Einfüge-, Bearbeitungs- oder Löschfunktionen der GridView-, DetailsView- oder FormView-Steuerelemente wird eine Vielzahl von Schritten transpiriert, wenn der Endbenutzer den Vorgang zum Hinzufügen eines neuen Datensatzes oder aktualisieren oder Löschen eines vorhandenen Datensatzes ausführt. Wie im vorherigen Lernprogramm erläutert, wird die Schaltfläche "Bearbeiten" durch die Schaltfläche "Aktualisieren" und "Abbrechen" ersetzt, wenn eine Zeile in "GridView" bearbeitet wird, und die BoundFields werden in TextBoxes umgewandelt. Nachdem der Endbenutzer die Daten aktualisiert und auf "Aktualisieren" klickt, werden die folgenden Schritte nach dem Postback ausgeführt:

  1. Das GridView füllt seine ObjectDataSource UpdateParameters mit den eindeutigen Identifikationsfeldern des bearbeiteten Datensatzes (über die DataKeyNames Eigenschaft) zusammen mit den vom Benutzer eingegebenen Werten auf.
  2. GridView ruft die ObjectDataSource-Methode Update() auf, die wiederum die entsprechende Methode im zugrunde liegenden Objekt aufruft (ProductsDAL.UpdateProductin unserem vorherigen Lernprogramm)
  3. Die zugrunde liegenden Daten, die jetzt die aktualisierten Änderungen enthalten, werden an gridView rebound to the GridView

In dieser Abfolge von Schritten wird eine Reihe von Ereignissen ausgelöst, sodass wir Ereignishandler erstellen können, um bei Bedarf benutzerdefinierte Logik hinzuzufügen. Beispielsweise wird vor Schritt 1 das GridView-Ereignis RowUpdating ausgelöst. An diesem Punkt können wir die Updateanforderung abbrechen, wenn ein Überprüfungsfehler auftritt. Wenn die Update() Methode aufgerufen wird, wird das ObjectDataSource-Ereignis Updating ausgelöst und bietet die Möglichkeit, die Werte eines der Objekte UpdateParametershinzuzufügen oder anzupassen. Nachdem die Methode des zugrunde liegenden Objekts des ObjectDataSource Updated ausgeführt wurde, wird das Objektereignis ausgelöst. Ein Ereignishandler für das Updated Ereignis kann die Details zum Aktualisierungsvorgang prüfen, z. B. die Anzahl der betroffenen Zeilen und ob eine Ausnahme aufgetreten ist. Schließlich wird nach Schritt 2 das GridView-Ereignis RowUpdated ausgelöst. Ein Ereignishandler für dieses Ereignis kann zusätzliche Informationen zum soeben ausgeführten Aktualisierungsvorgang untersuchen.

Abbildung 1 zeigt diese Reihe von Ereignissen und Schritten beim Aktualisieren einer GridView. Das Ereignismuster in Abbildung 1 ist nicht für die Aktualisierung mit einer GridView eindeutig. Durch Einfügen, Aktualisieren oder Löschen von Daten aus gridView, DetailsView oder FormView wird die gleiche Abfolge von Ereignissen vor und nach der Ebene sowohl für das Datenwebsteuerelement als auch für objectDataSource ausgelöst.

Eine Reihe von Vor- und Nachereignissen wird ausgelöst, wenn Daten in einer GridView aktualisiert werden

Abbildung 1: Eine Reihe von Vor- und Nachereignissen wird ausgelöst, wenn Daten in einer GridView aktualisiert werden (Klicken Sie, um das Bild in voller Größe anzuzeigen)

In diesem Lernprogramm untersuchen wir die Verwendung dieser Ereignisse, um die integrierten Einfüge-, Aktualisierungs- und Löschfunktionen der ASP.NET Datenwebsteuerelemente zu erweitern. Außerdem erfahren Sie, wie Sie die Bearbeitungsschnittstelle so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.

Schritt 1: Aktualisieren von ProduktProductName- undUnitPriceFeldern

In den Bearbeitungsschnittstellen aus dem vorherigen Lernprogramm mussten alle Produktfelder, die nicht schreibgeschützt waren, einbezogen werden. Wenn wir ein Feld aus der GridView entfernen würden , sagen wir QuantityPerUnit , beim Aktualisieren der Daten würde das Datenwebsteuerelement den Wert von QuantityPerUnit UpdateParameters ObjectDataSource nicht festlegen. Die ObjectDataSource würde dann einen null Wert an die UpdateProduct BLL-Methode (Business Logic Layer) übergeben, wodurch die Spalte des QuantityPerUnit bearbeiteten Datenbankdatensatzes in einen NULL Wert geändert würde. Wenn ein erforderliches Feld, z ProductName. B. , aus der Bearbeitungsschnittstelle entfernt wird, schlägt die Aktualisierung mit einer Ausnahme vom Typ "Spalte "ProductName" keine NULL-Ausnahme zu. Der Grund für dieses Verhalten war, dass die ObjectDataSource so konfiguriert wurde, dass die Methode der ProductsBLL Klasse UpdateProduct aufgerufen wird, die einen Eingabeparameter für die einzelnen Produktfelder erwartet hat. Daher enthielt die ObjectDataSource-Auflistung UpdateParameters einen Parameter für jeden Eingabeparameter der Methode.

Wenn wir ein Datenwebsteuerelement bereitstellen möchten, mit dem der Endbenutzer nur eine Teilmenge von Feldern aktualisieren kann, müssen wir entweder programmgesteuert die fehlenden UpdateParameters Werte im Ereignishandler von Updating ObjectDataSource festlegen oder eine BLL-Methode erstellen und aufrufen, die nur eine Teilmenge der Felder erwartet. Lassen Sie uns diesen ansatz untersuchen.

Insbesondere erstellen wir eine Seite, die nur die ProductName Felder UnitPrice in einer bearbeitbaren GridView anzeigt. Über die Bearbeitungsoberfläche von GridView kann der Benutzer nur die beiden angezeigten Felder und die beiden angezeigten Felder ProductName UnitPriceaktualisieren. Da diese Bearbeitungsschnittstelle nur eine Teilmenge der Felder eines Produkts bereitstellt, müssen wir entweder eine ObjectDataSource erstellen, die die vorhandene BLL-Methode UpdateProduct verwendet und die fehlenden Produktfeldwerte programmgesteuert in ihrem Updating Ereignishandler festgelegt hat, oder wir müssen eine neue BLL-Methode erstellen, die nur die Teilmenge von Feldern erwartet, die in der GridView definiert sind. In diesem Lernprogramm verwenden wir die letztere Option und erstellen eine Überladung der UpdateProduct Methode, die nur drei Eingabeparameter einnimmt: productName, , unitPriceund 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;
}

Wie bei der ursprünglichen UpdateProduct Methode überprüft diese Überladung zunächst, ob ein Produkt in der Datenbank mit dem angegebenen Element vorhanden ProductIDist. Andernfalls wird ein Fehler zurückgegeben false, der angibt, dass die Anforderung zum Aktualisieren der Produktinformationen fehlgeschlagen ist. Andernfalls aktualisiert sie die vorhandenen Produktdatensätze ProductName und Felder entsprechend und UnitPrice führt einen Commit für das Update durch Aufrufen der TableAdapter-Methode Update() durch Übergeben der ProductsRow Instanz durch.

Mit dieser Ergänzung zu unserer ProductsBLL Klasse können wir die vereinfachte GridView-Schnittstelle erstellen. Öffnen Sie den DataModificationEvents.aspx Ordner, EditInsertDelete und fügen Sie der Seite eine GridView hinzu. Erstellen Sie eine neue ObjectDataSource, und konfigurieren Sie sie so, dass die Klasse mit der ProductsBLL Select() Methodenzuordnung und der Update() Methodenzuordnung GetProducts zu der UpdateProduct Überladung verwendet wird, die nur die productNameParameter und unitPriceproductID Eingabeparameter einnimmt. Abbildung 2 zeigt den Assistenten zum Erstellen von Datenquellen, wenn die Methode von ObjectDataSource Update() der neuen UpdateProduct Methodenüberladung der ProductsBLL Klasse zugeordnet wird.

Zuordnen der Update()-Methode von ObjectDataSource zur Neuen UpdateProduct-Überladung

Abbildung 2: Zuordnen der Methode von ObjectDataSource Update() zur neuen UpdateProduct Überladung (Klicken, um das Bild in voller Größe anzuzeigen)

Da unser Beispiel zunächst nur die Möglichkeit benötigt, Daten zu bearbeiten, aber keine Datensätze einzufügen oder zu löschen, nehmen Sie sich einen Moment Zeit, um explizit anzugeben, dass die Methoden und Delete() Methoden von ObjectDataSource Insert() keiner der Methoden der ProductsBLL Klasse zugeordnet werden sollten, indem Sie zu den REGISTERKARTEn INSERT und DELETE wechseln und (Keine) aus der Dropdownliste auswählen.

Choose (None) From the Drop-Down List for the INSERT and DELETE Tabs

Abbildung 3: Auswählen (Keine) Aus der Dropdownliste für die REGISTERKARTEN EINFÜGEN und LÖSCHEN (Klicken, um das Bild in voller Größe anzuzeigen)

Aktivieren Sie nach Abschluss dieses Assistenten das Kontrollkästchen "Bearbeitung aktivieren" aus dem Smarttag von GridView.

Mit Abschluss des Assistenten zum Erstellen von Datenquellen und der Bindung an gridView hat Visual Studio die deklarative Syntax für beide Steuerelemente erstellt. Wechseln Sie zur Quellansicht, um das deklarative Markup von ObjectDataSource zu prüfen, das unten dargestellt wird:

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

Da es keine Zuordnungen für die ObjectDataSource-Elemente Insert() und Delete() -Methoden gibt, gibt es keine InsertParameters Abschnitte oder DeleteParameters Abschnitte. Da die Update() Methode der UpdateProduct Methodenüberladung zugeordnet ist, die nur drei Eingabeparameter akzeptiert, weist der UpdateParameters Abschnitt nur drei Parameter Instanzen auf.

Beachten Sie, dass die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0}. Diese Eigenschaft wird automatisch von Visual Studio bei Verwendung des Assistenten zum Konfigurieren der Datenquelle festgelegt. Da unsere BLL-Methoden jedoch nicht erwarten, dass der ursprüngliche ProductID Wert übergeben wird, entfernen Sie diese Eigenschaftszuweisung vollständig aus der deklarativen Syntax von ObjectDataSource.

Hinweis

Wenn Sie einfach den OldValuesParameterFormatString Eigenschaftswert aus dem Eigenschaftenfenster in der Entwurfsansicht löschen, ist die Eigenschaft weiterhin in der deklarativen Syntax vorhanden, wird jedoch auf eine leere Zeichenfolge festgelegt. Entfernen Sie die Eigenschaft entweder vollständig aus der deklarativen Syntax, oder legen Sie den Wert aus dem Eigenschaftenfenster auf den Standardwert fest. {0}

Während die ObjectDataSource nur für den Namen, den Preis und die ID des Produkts verfügt UpdateParameters , hat Visual Studio für jedes der Felder des Produkts ein BoundField- oder CheckBoxField-Objekt in gridView hinzugefügt.

Die GridView enthält ein BoundField- oder CheckBoxField-Element für jedes der Felder des Produkts.

Abbildung 4: Die GridView enthält ein BoundField- oder CheckBoxField-Element für jedes der Felder des Produkts (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Wenn der Endbenutzer ein Produkt bearbeitet und auf die Schaltfläche "Aktualisieren" klickt, listet gridView die Felder auf, die nicht schreibgeschützt waren. Anschließend wird der Wert des entsprechenden Parameters in der ObjectDataSource-Auflistung UpdateParameters auf den vom Benutzer eingegebenen Wert festgelegt. Wenn kein entsprechender Parameter vorhanden ist, fügt gridView der Auflistung einen hinzu. Wenn unsere GridView "BoundFields" und "CheckBoxFields" für alle Felder des Produkts enthält, wird die ObjectDataSource daher die UpdateProduct Überladung aufrufen, die alle diese Parameter einnimmt, obwohl das deklarative Markup von ObjectDataSource nur drei Eingabeparameter angibt (siehe Abbildung 5). Wenn es eine Kombination aus nicht schreibgeschützten Produktfeldern in der GridView gibt, die nicht den Eingabeparametern für eine UpdateProduct Überladung entsprechen, wird beim Versuch, eine Aktualisierung zu aktualisieren, eine Ausnahme ausgelöst.

Die GridView fügt Parameter zur UpdateParameters-Auflistung von ObjectDataSource hinzu.

Abbildung 5: Die GridView fügt Parameter zur ObjektDatenquelle-Auflistung UpdateParameters hinzu (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um sicherzustellen, dass die ObjectDataSource die UpdateProduct Überladung aufruft, die nur den Namen, den Preis und die ID des Produkts einnimmt, müssen wir die GridView auf bearbeitbare Felder nur für das und UnitPricedie ProductName . Dies kann erreicht werden, indem die anderen BoundFields und CheckBoxFields entfernt werden, indem Sie die Eigenschaft dieser anderen Felder auf trueoder durch eine Kombination der beiden Felder ReadOnly festlegen. In diesem Lernprogramm entfernen wir einfach alle GridView-Felder mit Ausnahme der ProductName " UnitPrice BoundFields", nach denen das deklarative Markup von GridView wie folgt aussieht:

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

Obwohl die UpdateProduct Überladung drei Eingabeparameter erwartet, verfügen wir nur über zwei BoundFields in unserer GridView. Dies liegt daran, dass der productID Eingabeparameter ein Primärschlüsselwert ist und über den Wert der DataKeyNames Eigenschaft für die bearbeitete Zeile übergeben wird.

Unsere GridView ermöglicht es einem Benutzer, UpdateProduct nur den Namen und den Preis eines Produkts zu bearbeiten, ohne die anderen Produktfelder zu verlieren.

Die Schnittstelle ermöglicht das Bearbeiten nur des Namens und des Preises des Produkts.

Abbildung 6: Die Benutzeroberfläche ermöglicht die Bearbeitung nur des Produktnamens und des Preises (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Wie im vorherigen Lernprogramm erläutert, ist es wichtig, dass der Ansichtszustand von GridView aktiviert ist (standardverhalten). Wenn Sie die GridView-Eigenschaft auf false"GridView" EnableViewState festlegen, besteht das Risiko, dass gleichzeitige Benutzer versehentlich Datensätze löschen oder bearbeiten.

Verbessern derUnitPriceFormatierung

Obwohl das in Abbildung 6 gezeigte GridView-Beispiel funktioniert, ist das UnitPrice Feld überhaupt nicht formatiert, was zu einer Preisanzeige führt, die keine Währungssymbole enthält und vier Dezimalstellen aufweist. Wenn Sie eine Währungsformatierung für die nicht bearbeitbaren Zeilen anwenden möchten, legen Sie einfach die Eigenschaft von DataFormatString BoundField auf {0:c} und deren HtmlEncode Eigenschaft auf false.UnitPrice

Festlegen der DataFormatString- und HtmlEncode-Eigenschaften von UnitPrice entsprechend

Abbildung 7: Festlegen der Eigenschaften und ' UnitPrices DataFormatString ' HtmlEncode entsprechend (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Bei dieser Änderung formatieren die nicht bearbeitbaren Zeilen den Preis als Währung; Die bearbeitete Zeile zeigt jedoch weiterhin den Wert ohne Währungssymbol und mit vier Dezimalstellen an.

Nicht bearbeitbare Zeilen sind jetzt als Währungswerte formatiert.

Abbildung 8: Nicht bearbeitbare Zeilen sind jetzt als Währungswerte formatiert (Zum Anzeigen des Bilds mit voller Größe klicken)

Die in der DataFormatString Eigenschaft angegebenen Formatierungsanweisungen können auf die Bearbeitungsschnittstelle angewendet werden, indem sie die Eigenschaft " ApplyFormatInEditMode BoundField" auf true "(Standardeinstellung) falsefestlegen. Nehmen Sie sich einen Moment Zeit, um diese Eigenschaft auf .true

Festlegen der ApplyFormatInEditMode-Eigenschaft von UnitPrice BoundField auf

Abbildung 9: Festlegen der Eigenschaft des UnitPrice ApplyFormatInEditMode BoundFields auf true (Klicken, um das Bild in voller Größe anzuzeigen)

Bei dieser Änderung wird der Wert der UnitPrice in der bearbeiteten Zeile angezeigten Zeile auch als Währung formatiert.

Screenshot der GridView mit dem UnitPrice-Wert der bearbeiteten Zeile, der als Währung formatiert ist.

Abbildung 10: Der Wert der bearbeiteten Zeile UnitPrice ist jetzt als Währung formatiert (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Beim Aktualisieren eines Produkts mit dem Währungssymbol im Textfeld wie 19,00 $ wird jedoch ein FormatException. Wenn gridView versucht, die vom Benutzer bereitgestellten Werte der ObjectDataSource-Auflistung UpdateParameters zuzuweisen, kann die UnitPrice Zeichenfolge "$19.00" nicht in den decimal erforderlichen Parameter konvertiert werden (siehe Abbildung 11). Um dies zu beheben, können wir einen Ereignishandler für das GridView-Ereignis RowUpdating UnitPrice erstellen und den vom Benutzer bereitgestellten als währungsformatiert decimalanalysieren lassen.

Das GridView-Ereignis RowUpdating akzeptiert als zweiten Parameter ein Objekt vom Typ GridViewUpdateEventArgs, das ein NewValues Wörterbuch als eine seiner Eigenschaften enthält, die die vom Benutzer bereitgestellten Werte enthalten, die bereit sind, der ObjectDataSource-Auflistung UpdateParameters zuzuordnen. Wir können den vorhandenen UnitPrice Wert in der NewValues Auflistung mit einem dezimalen Wert überschreiben, der mithilfe des Währungsformats mit den folgenden Codezeilen im RowUpdating Ereignishandler analysiert wird:

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

Wenn der Benutzer einen UnitPrice Wert (z. B. "$19,00") angegeben hat, wird dieser Wert mit dem durch Decimal.Parse berechneten Dezimalwert überschrieben, wobei der Wert als Währung analysiert wird. Dadurch wird das Dezimalzeichen korrekt analysiert, wenn Währungssymbole, Kommas, Dezimalkomma usw. vorhanden sind, und die NumberStyles-Aufzählung im System.Globalization-Namespace verwendet wird.

Abbildung 11 zeigt sowohl das Problem, das durch Währungssymbole im vom Benutzer bereitgestellten UnitPriceBenutzer verursacht wird, als auch, wie der Ereignishandler von RowUpdating GridView verwendet werden kann, um diese Eingabe korrekt zu analysieren.

Diagramm, das zeigt, wie objectDataSource das UnitPrice-Feld verarbeitet und wie der RowUpdate-Ereignishandler der GridView eine Zeichenfolge in eine Dezimalzahl konvertiert.

Abbildung 11: Der Wert der bearbeiteten Zeile UnitPrice ist jetzt als Währung formatiert (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Schritt 2: VerbietenNULL UnitPrices

Während die Datenbank so konfiguriert ist, dass Werte in der Spalte der Tabelle zulässig NULL sind, möchten wir möglicherweise verhindern, dass Benutzer, die diese bestimmte Seite besuchen, einen NULL UnitPrice Wert UnitPrice angeben.Products Das heißt, wenn ein Benutzer beim Bearbeiten einer Produktzeile keinen UnitPrice Wert eingeben kann, anstatt die Ergebnisse in der Datenbank zu speichern, wird eine Meldung angezeigt, in der der Benutzer darüber informiert wird, dass auf dieser Seite alle bearbeiteten Produkte über einen angegebenen Preis verfügen müssen.

Das GridViewUpdateEventArgs objekt, das an den Ereignishandler von RowUpdating GridView übergeben wird, enthält eine Cancel Eigenschaft, die, falls festgelegt, trueden Aktualisierungsprozess beendet. Erweitern wir den RowUpdating Ereignishandler so, dass er auf true eine Meldung festgelegt e.Cancel und angezeigt wird, in der erläutert wird, warum der UnitPrice Wert in der NewValues Auflistung istnull.

Fügen Sie zunächst ein Bezeichnungswebsteuerelement zur Seite mit dem Namen hinzu MustProvideUnitPriceMessage. Dieses Bezeichnungssteuerelement wird angezeigt, wenn der Benutzer beim Aktualisieren eines Produkts keinen UnitPrice Wert angeben kann. Legen Sie die Eigenschaft des Etiketts Text auf "Sie müssen einen Preis für das Produkt angeben". Ich habe auch eine neue CSS-Klasse mit Styles.css Warning der folgenden Definition erstellt:

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

Legen Sie schließlich die Eigenschaft der Bezeichnung CssClass auf Warning. An diesem Punkt sollte der Designer die Warnmeldung in einer roten, fett formatierten, kursiven, zusätzlichen großen Schriftgröße oberhalb der GridView anzeigen, wie in Abbildung 12 dargestellt.

Eine Beschriftung wurde oberhalb der GridView hinzugefügt.

Abbildung 12: Eine Beschriftung wurde oberhalb der GridView hinzugefügt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Diese Bezeichnung sollte standardmäßig ausgeblendet werden. Legen Sie daher die Visible Page_Load Eigenschaft im Ereignishandler festfalse:

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

Wenn der Benutzer versucht, ein Produkt ohne Angabe UnitPricezu aktualisieren, möchten wir das Update abbrechen und die Warnbezeichnung anzeigen. Erweitern Sie den GridView-Ereignishandler RowUpdating wie folgt:

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

Wenn ein Benutzer versucht, ein Produkt zu speichern, ohne einen Preis anzugeben, wird das Update abgebrochen und eine hilfreiche Meldung angezeigt. Während die Datenbank (und Geschäftslogik) s zulässt NULL UnitPrice , ist diese bestimmte ASP.NET Seite nicht möglich.

Ein Benutzer kann

Abbildung 13: Ein Benutzer darf nicht leer lassen UnitPrice (Klicken, um das Bild in voller Größe anzuzeigen)

Bisher haben wir gesehen, wie sie das GridView-Ereignis RowUpdating verwenden, um die Parameterwerte, die der ObjectDataSource-Auflistung UpdateParameters zugewiesen sind, programmgesteuert zu ändern und den Aktualisierungsprozess vollständig abzubrechen. Diese Konzepte übernehmen die DetailsView- und FormView-Steuerelemente und gelten auch für das Einfügen und Löschen.

Diese Aufgaben können auch auf ObjectDataSource-Ebene über Ereignishandler für die zugehörigen InsertingEreignisse Updatingund Deleting Ereignisse ausgeführt werden. Diese Ereignisse werden ausgelöst, bevor die zugeordnete Methode des zugrunde liegenden Objekts aufgerufen wird, und bieten die Möglichkeit, die Eingabeparameterauflistung zu ändern oder den Vorgang direkt abzubrechen. Die Ereignishandler für diese drei Ereignisse werden an ein Objekt vom Typ ObjectDataSourceMethodEventArgs übergeben, das zwei interessante Eigenschaften aufweist:

  • Cancel, which, if set to true, cancels the operation being being perform
  • InputParameters, die die Auflistung von InsertParameters, , UpdateParametersoder DeleteParameters, abhängig davon, ob der Ereignishandler für das Inserting, Updating, oder Deleting Ereignis

Um die Arbeit mit den Parameterwerten auf ObjectDataSource-Ebene zu veranschaulichen, fügen wir eine DetailsView auf unserer Seite hinzu, mit der benutzer ein neues Produkt hinzufügen können. Diese DetailsView wird verwendet, um eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts zur Datenbank bereitzustellen. Um eine konsistente Benutzeroberfläche beim Hinzufügen eines neuen Produkts beizubehalten, erlauben wir es dem Benutzer, nur Werte für die felder und UnitPrice die ProductName Werte einzugeben. Standardmäßig werden diese Werte, die nicht in der Einfügeschnittstelle von DetailsView angegeben sind, auf einen NULL Datenbankwert festgelegt. Wir können jedoch das ObjectDataSource-Ereignis Inserting verwenden, um unterschiedliche Standardwerte einzuordnen, da wir in Kürze sehen werden.

Schritt 3: Bereitstellen einer Schnittstelle zum Hinzufügen neuer Produkte

Ziehen Sie eine DetailsView aus der Toolbox auf den Designer oberhalb der GridView, löschen Sie die zugehörigen Height Und Width Eigenschaften, und binden Sie sie an die ObjectDataSource, die bereits auf der Seite vorhanden ist. Dadurch wird ein BoundField- oder CheckBoxField-Element für jedes der Felder des Produkts hinzugefügt. Da wir diese DetailsView zum Hinzufügen neuer Produkte verwenden möchten, müssen wir die Option "Einfügen aktivieren" aus dem Smarttag überprüfen. Es gibt jedoch keine solche Option, da die Methode von Insert() ObjectDataSource nicht einer Methode in der ProductsBLL Klasse zugeordnet ist (erinnern Sie sich daran, dass wir diese Zuordnung beim Konfigurieren der Datenquelle auf (Keine) festlegen, siehe Abbildung 3).

Um die ObjectDataSource zu konfigurieren, wählen Sie den Link "Datenquelle konfigurieren" aus dem Smarttag aus, und starten Sie den Assistenten. Auf dem ersten Bildschirm können Sie das zugrunde liegende Objekt ändern, an das ObjectDataSource gebunden ist; lassen Sie sie auf ProductsBLL. Im nächsten Bildschirm werden die Zuordnungen aus den Methoden der ObjectDataSource zu den zugrunde liegenden Objekten aufgelistet. Obwohl wir explizit angegeben haben, dass die Insert() Methoden und Delete() Methoden keiner Methode zugeordnet werden sollten, sehen Sie, dass eine Zuordnung vorhanden ist, wenn Sie zu den Registerkarten INSERT und DELETE wechseln. Dies liegt daran, dass die ProductsBLL's AddProduct und DeleteProduct Methoden das DataObjectMethodAttribute Attribut verwenden, um anzugeben, dass sie die Standardmethoden für Insert() bzw Delete(). beide sind. Daher wählt der ObjectDataSource-Assistent diese jedes Mal aus, wenn Sie den Assistenten ausführen, es sei denn, es wird ein anderer Wert explizit angegeben.

Belassen Sie die Methode, die auf die Insert() AddProduct Methode zeigt, legen Sie aber erneut die Dropdownliste der DELETE-Registerkarte auf (Keine) fest.

Festlegen der Dropdownliste der INSERT-Registerkarte auf die AddProduct-Methode

Abbildung 14: Festlegen der Dropdownliste der INSERT-Registerkarte auf die AddProduct Methode (Klicken, um das Bild in voller Größe anzuzeigen)

Festlegen der Dropdownliste der DELETE-Registerkarte auf (Keine)

Abbildung 15: Festlegen der Dropdownliste der DELETE-Registerkarte auf (Keine) (Klicken, um das Bild in voller Größe anzuzeigen)

Nachdem Sie diese Änderungen vorgenommen haben, wird die deklarative Syntax von ObjectDataSource um eine InsertParameters Auflistung erweitert, wie unten dargestellt:

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

Erneutes Ausführen des Assistenten, der die OldValuesParameterFormatString Eigenschaft wieder hinzugefügt hat. Nehmen Sie sich einen Moment Zeit, um diese Eigenschaft zu löschen, indem Sie sie auf den Standardwert ({0}) festlegen oder sie vollständig aus der deklarativen Syntax entfernen.

Mit der ObjectDataSource, die Einfügefunktionen bereitstellt, enthält das Smarttag von DetailsView nun das Kontrollkästchen "Einfügen aktivieren". kehren Sie zum Designer zurück, und aktivieren Sie diese Option. Analysieren Sie als Nächstes die DetailsView so, dass nur zwei BoundFields - ProductName und UnitPrice das CommandField - vorhanden sind. An diesem Punkt sollte die deklarative Syntax von DetailsView wie folgt aussehen:

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

Abbildung 16 zeigt diese Seite, wenn sie an diesem Punkt durch einen Browser angezeigt wird. Wie Sie sehen können, listet die DetailsView den Namen und den Preis des ersten Produkts (Chai) auf. Was wir möchten, ist jedoch eine Einfügeschnittstelle, die dem Benutzer eine Möglichkeit bietet, schnell ein neues Produkt zur Datenbank hinzuzufügen.

Die DetailsView wird derzeit im schreibgeschützten Modus gerendert.

Abbildung 16: Die Detailansicht wird derzeit im schreibgeschützten Modus gerendert (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um die DetailsView im Einfügemodus anzuzeigen, müssen wir die DefaultMode Eigenschaft auf Insertingfestlegen. Dadurch wird die DetailsView beim ersten Besuch im Einfügemodus gerendert und nach dem Einfügen eines neuen Datensatzes dort beibehalten. Wie in Abbildung 17 dargestellt, bietet eine solche Detailansicht eine schnelle Schnittstelle zum Hinzufügen eines neuen Datensatzes.

Die DetailsView bietet eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts.

Abbildung 17: Die Detailansicht bietet eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts (Klicken, um das Bild in voller Größe anzuzeigen)

Wenn der Benutzer einen Produktnamen und -preis eingibt (z. B. "Acme Water" und 1,99, wie in Abbildung 17 dargestellt), und klickt auf "Einfügen", beginnt ein Postback und der einzufügende Workflow beginnt, was zu einem neuen Produktdatensatz führt, der der Datenbank hinzugefügt wird. Die DetailsView verwaltet die Einfügeschnittstelle, und GridView wird automatisch an die Datenquelle gebunden, um das neue Produkt einzuschließen, wie in Abbildung 18 dargestellt.

Das Produkt

Abbildung 18: Das Produkt "Acme Water" wurde der Datenbank hinzugefügt.

Obwohl die GridView in Abbildung 18 nicht angezeigt wird, werden den Produktfeldern, die von der DetailsView-Schnittstelle CategoryIDfehlen, QuantityPerUnitSupplierIDusw. Datenbankwerte zugewiesenNULL. Sie können dies sehen, indem Sie die folgenden Schritte ausführen:

  1. Wechseln zum Server-Explorer in Visual Studio
  2. Erweitern des NORTHWND.MDF Datenbankknotens
  3. Klicken Sie mit der rechten Maustaste auf den Products Datenbanktabellenknoten.
  4. Wählen Sie "Tabellendaten anzeigen" aus.

Dadurch werden alle Datensätze in der Products Tabelle aufgeführt. Wie in Abbildung 19 dargestellt, sind alle Spalten des neuen Produkts anders als ProductID, ProductNameund UnitPrice haben NULL Werte.

Die in der DetailsView nicht bereitgestellten Produktfelder sind zugewiesene NULL-Werte.

Abbildung 19: Die in der DetailAnsicht nicht bereitgestellten Produktfelder sind zugewiesene NULL Werte (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Möglicherweise möchten wir einen anderen Standardwert als NULL für einen oder mehrere dieser Spaltenwerte bereitstellen, entweder weil NULL es sich nicht um die beste Standardoption handelt oder weil die Datenbankspalte selbst dies nicht zulässt NULL . Dazu können wir die Werte der Parameter der DetailsView-Auflistung InputParameters programmgesteuert festlegen. Diese Zuweisung kann entweder im Ereignishandler für das Ereignis von ItemInserting DetailsView oder das ObjectDataSource-Ereignis Inserting erfolgen. Da wir bereits die Ereignisse vor und nach der Ebene des Datenwebsteuerelements verwendet haben, untersuchen wir dieses Mal die Verwendung der Ereignisse von ObjectDataSource.

Schritt 4: Zuweisen von Werten zu denCategoryIDUndSupplierIDParametern

In diesem Lernprogramm stellen wir uns vor, dass für unsere Anwendung beim Hinzufügen eines neuen Produkts über diese Schnittstelle ein CategoryID Wert von 1 zugewiesen SupplierID werden sollte. Wie bereits erwähnt, weist ObjectDataSource ein Paar ereignisse vor und nach der Ebene auf, die während des Datenänderungsprozesses ausgelöst werden. Wenn die Insert() Methode aufgerufen wird, löst ObjectDataSource zunächst das Inserting Ereignis aus, ruft dann die Methode auf, der die Insert() Methode zugeordnet wurde, und löst schließlich das Inserted Ereignis aus. Der Inserting Ereignishandler bietet uns eine letzte Gelegenheit, die Eingabeparameter zu optimieren oder den Vorgang direkt abzubrechen.

Hinweis

In einer realen Anwendung möchten Sie wahrscheinlich entweder zulassen, dass der Benutzer die Kategorie und den Lieferanten angeben oder diesen Wert für sie basierend auf einigen Kriterien oder Geschäftslogik auswählen würde (anstatt blind eine ID von 1 auszuwählen). Unabhängig davon veranschaulicht das Beispiel, wie der Wert eines Eingabeparameters programmgesteuert aus dem Ereignis vor der Ebene von ObjectDataSource festgelegt wird.

Nehmen Sie sich einen Moment Zeit, um einen Ereignishandler für das ObjectDataSource-Ereignis Inserting zu erstellen. Beachten Sie, dass der zweite Eingabeparameter des Ereignishandlers ein Objekt vom Typ ObjectDataSourceMethodEventArgsist, das über eine Eigenschaft für den Zugriff auf die Parameterauflistung () und eine Eigenschaft zum Abbrechen des Vorgangs (InputParametersCancel) verfügt.

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{

}

An diesem Punkt enthält die InputParameters Eigenschaft die ObjectDataSource-Auflistung InsertParameters mit den Werten, die aus der DetailsView zugewiesen wurden. Um den Wert eines dieser Parameter zu ändern, verwenden Sie einfach Folgendes: e.InputParameters["paramName"] = value. Um die CategoryID Werte SupplierID von 1 festzulegen, passen Sie daher den Inserting Ereignishandler so an, dass er wie folgt aussieht:

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

Dieses Mal werden beim Hinzufügen eines neuen Produkts (z. B. Acme Soda) die CategoryID Spalten SupplierID und Spalten des neuen Produkts auf 1 festgelegt (siehe Abbildung 20).

Neue Produkte haben jetzt die Werte

Abbildung 20: Neue Produkte verfügen jetzt über " CategoryID 1" und SupplierID "Werte" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Zusammenfassung

Während des Bearbeitungs-, Einfügen- und Löschvorgangs durchlaufen sowohl das Datenwebsteuerelement als auch die ObjectDataSource eine Reihe von Ereignissen vor und nach der Ebene. In diesem Lernprogramm haben wir die Ereignisse vor der Ebene untersucht und gezeigt, wie Sie diese verwenden können, um die Eingabeparameter anzupassen oder den Datenänderungsvorgang vollständig aus den Ereignissen des Datenwebsteuerelements und objectDataSource abzubrechen. Im nächsten Lernprogramm befassen wir uns mit dem Erstellen und Verwenden von Ereignishandlern für die Ereignisse nach der Ebene.

Glückliche Programmierung!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann über mitchell@4GuysFromRolla.com seinen Blog erreicht werden, der unter .http://ScottOnWriting.NET

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Jackie Goor und Liz Shulok. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn dies der Fall ist, legen Sie mir eine Zeile bei mitchell@4GuysFromRolla.com.