Share via


Aktualisieren und Löschen von vorhandenen Binärdaten (C#)

von Scott Mitchell

PDF herunterladen

In früheren Tutorials haben wir erfahren, wie das GridView-Steuerelement das Bearbeiten und Löschen von Textdaten vereinfacht. In diesem Tutorial erfahren Sie, wie das GridView-Steuerelement auch das Bearbeiten und Löschen von Binärdaten ermöglicht, unabhängig davon, ob diese Binärdaten in der Datenbank oder im Dateisystem gespeichert werden.

Einführung

In den letzten drei Tutorials haben wir einige Funktionen für die Arbeit mit Binärdaten hinzugefügt. Wir haben zunächst eine BrochurePathCategories Spalte zur Tabelle hinzugefügt und die Architektur entsprechend aktualisiert. Wir haben auch Methoden für datenzugriffsschicht und Geschäftslogikebene hinzugefügt, um mit der vorhandenen Picture Spalte der Categories-Tabelle zu arbeiten, die die binären Inhalte einer Bilddatei enthält. Wir haben Webseiten erstellt, um die Binärdaten in einem GridView einen Downloadlink für die Broschüre mit dem Kategoriebild in einem <img> Element zu präsentieren, und haben eine DetailsView hinzugefügt, damit Benutzer eine neue Kategorie hinzufügen und ihre Broschüren- und Bilddaten hochladen können.

Es bleibt nur noch die Möglichkeit, vorhandene Kategorien zu bearbeiten und zu löschen. Dies wird in diesem Tutorial mithilfe der integrierten Bearbeitungs- und Löschfunktionen von GridView erreicht. Beim Bearbeiten einer Kategorie kann der Benutzer optional ein neues Bild hochladen oder die Kategorie weiterhin das vorhandene bild verwenden. Für die Broschüre können sie entweder die vorhandene Broschüre verwenden, eine neue Broschüre hochladen oder angeben, dass der Kategorie keine Broschüre mehr zugeordnet ist. Lassen Sie uns loslegen!

Schritt 1: Aktualisieren der Datenzugriffsebene

Die DAL verfügt über automatisch generierte InsertMethoden , UpdateundDelete, diese Methoden wurden jedoch basierend auf der CategoriesTableAdapter Abfrage s Standard generiert, die die Picture Spalte nicht enthält. Daher enthalten die Insert Methoden und Update keine Parameter zum Angeben der Binärdaten für das Bild der Kategorie. Wie im vorherigen Tutorial müssen wir beim Angeben von Binärdaten eine neue TableAdapter-Methode zum Aktualisieren der Categories Tabelle erstellen.

Öffnen Sie das typisierte DataSet, und klicken Sie im Designer mit der rechten Maustaste auf die CategoriesTableAdapter Kopfzeile s, und wählen Sie im Kontextmenü Abfrage hinzufügen aus, um den TableAdapter-Abfragekonfigurations-Assistenten zu starten. Dieser Assistent fragt uns zunächst, wie die TableAdapter-Abfrage auf die Datenbank zugreifen soll. Wählen Sie SQL-Anweisungen verwenden aus, und klicken Sie auf Weiter. Im nächsten Schritt wird zur Eingabe des Typs der zu generierenden Abfrage aufgefordert. Da wir eine Abfrage zum Hinzufügen eines neuen Datensatzes Categories zur Tabelle erstellen, wählen Sie AKTUALISIEREN aus, und klicken Sie auf Weiter.

Wählen Sie die Option UPDATE aus.

Abbildung 1: Auswählen der Option "UPDATE" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Wir müssen jetzt die SQL-Anweisung UPDATE angeben. Der Assistent schlägt automatisch eine UPDATE Anweisung vor, die der Standard abfrage von TableAdapter entspricht (eine Abfrage, die die CategoryNameWerte , Descriptionund BrochurePath aktualisiert). Ändern Sie die -Anweisung so, dass die Picture Spalte zusammen mit einem @Picture Parameter eingeschlossen wird, wie folgt:

UPDATE [Categories] SET 
    [CategoryName] = @CategoryName, 
    [Description] = @Description, 
    [BrochurePath] = @BrochurePath ,
    [Picture] = @Picture
WHERE (([CategoryID] = @Original_CategoryID))

Der letzte Bildschirm des Assistenten fordert uns auf, die neue TableAdapter-Methode zu benennen. Geben Sie ein, UpdateWithPicture und klicken Sie auf Fertig stellen.

Nennen Sie die neue TableAdapter-Methode UpdateWithPicture.

Abbildung 2: Name der neuen TableAdapter-Methode UpdateWithPicture (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 2: Hinzufügen der Geschäftslogikebenenmethoden

Zusätzlich zur Aktualisierung der DAL müssen wir die BLL aktualisieren, um Methoden zum Aktualisieren und Löschen einer Kategorie einzuschließen. Dies sind die Methoden, die von der Präsentationsebene aufgerufen werden.

Zum Löschen einer Kategorie können wir die CategoriesTableAdapter automatisch generierte Delete s-Methode verwenden. Fügen Sie der CategoriesBLL-Klasse die folgende Methode hinzu:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteCategory(int categoryID)
{
    int rowsAffected = Adapter.Delete(categoryID);
    // Return true if precisely one row was deleted, otherwise false
    return rowsAffected == 1;
}

In diesem Tutorial erstellen wir zwei Methoden zum Aktualisieren einer Kategorie: eine, die die binären Bilddaten erwartet und die Methode aufruft, die UpdateWithPicture wir gerade hinzugefügt haben, und eine andere Methode, die CategoriesTableAdapter nur die CategoryNameWerte , Descriptionund BrochurePath akzeptiert und die klasse s automatisch generierte Update Anweisung verwendetCategoriesTableAdapter. Der Grund für die Verwendung von zwei Methoden ist, dass ein Benutzer unter bestimmten Umständen das Kategoriebild zusammen mit seinen anderen Feldern aktualisieren möchte. In diesem Fall muss der Benutzer das neue Bild hochladen. Die hochgeladenen Bild-Binärdaten können dann in der UPDATE -Anweisung verwendet werden. In anderen Fällen ist der Benutzer möglicherweise nur daran interessiert, z. B. den Namen und die Beschreibung zu aktualisieren. Wenn die UPDATE Anweisung jedoch auch die Binärdaten für die Picture Spalte erwartet, müssen wir diese Informationen ebenfalls bereitstellen. Dies würde eine zusätzliche Reise zur Datenbank erfordern, um die Bilddaten für den zu bearbeitenden Datensatz wie folgt zu bringen. Daher möchten wir zwei UPDATE Methoden. Die Geschäftslogikebene bestimmt, welche verwendet werden soll, basierend darauf, ob Bilddaten beim Aktualisieren der Kategorie bereitgestellt werden.

Um dies zu vereinfachen, fügen Sie der -Klasse zwei Methoden hinzu, die CategoriesBLL beide den Namen haben UpdateCategory. Der erste sollte drei string s, ein byte Array und ein int als Eingabeparameter akzeptieren; der zweite, nur drei string s und ein int. Die string Eingabeparameter gelten für den Namen, die Beschreibung und den Pfad der Broschürendatei, das byte Array ist für den binären Inhalt des Kategoriebilds und der int identifiziert den CategoryID des zu aktualisierenden Datensatzes. Beachten Sie, dass die erste Überladung die zweite aufruft, wenn das übergebene byte Array lautet null:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateCategory(string categoryName, string description, 
    string brochurePath, byte[] picture, int categoryID)
{
    // If no picture is specified, use other overload
    if (picture == null)
        return UpdateCategory(categoryName, description, brochurePath, categoryID);
    // Update picture, as well
    int rowsAffected = Adapter.UpdateWithPicture
        (categoryName, description, brochurePath, picture, categoryID);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}
[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Update, true)]
public bool UpdateCategory(string categoryName, string description, 
    string brochurePath, int categoryID)
{
    int rowsAffected = Adapter.Update
        (categoryName, description, brochurePath, categoryID);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Schritt 3: Kopieren der Einfüge- und Ansichtsfunktionalität

Im vorherigen Tutorial haben wir eine Seite mit dem Namen UploadInDetailsView.aspx erstellt, auf der alle Kategorien in einer GridView aufgelistet sind, und eine DetailsView zum Hinzufügen neuer Kategorien zum System bereitgestellt. In diesem Tutorial erweitern wir GridView um Unterstützung für das Bearbeiten und Löschen. Anstatt weiter von zu arbeiten UploadInDetailsView.aspx, platzieren wir stattdessen die Änderungen dieses Tutorials auf der UpdatingAndDeleting.aspx Seite aus demselben Ordner, ~/BinaryData. Kopieren Sie das deklarative Markup und den Code aus, und fügen Sie ihn aus UploadInDetailsView.aspx in ein UpdatingAndDeleting.aspx.

Öffnen Sie zunächst die UploadInDetailsView.aspx Seite. Kopieren Sie die gesamte deklarative Syntax innerhalb des <asp:Content> Elements, wie in Abbildung 3 dargestellt. Öffnen Sie UpdatingAndDeleting.aspx als Nächstes dieses Markup, und fügen Sie es in das zugehörige <asp:Content> Element ein. Kopieren Sie auf ähnliche Weise den Code aus der CodeBehind-Klasse der UploadInDetailsView.aspx Seite in UpdatingAndDeleting.aspx.

Kopieren des deklarativen Markups aus UploadInDetailsView.aspx

Abbildung 3: Kopieren des deklarativen Markups aus UploadInDetailsView.aspx (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nachdem Sie das deklarative Markup und den Code kopiert haben, besuchen Sie UpdatingAndDeleting.aspx. Sie sollten die gleiche Ausgabe sehen und die gleiche Benutzeroberfläche wie die UploadInDetailsView.aspx Seite aus dem vorherigen Tutorial haben.

Schritt 4: Hinzufügen von Unterstützung für das Löschen von ObjectDataSource und GridView

Wie im Tutorial Eine Übersicht über das Einfügen, Aktualisieren und Löschen von Daten erläutert, bietet GridView integrierte Löschfunktionen, und diese Funktionen können beim Aktivieren eines Kontrollkästchens aktiviert werden, wenn die zugrunde liegende Datenquelle des Rasters das Löschen unterstützt. Derzeit unterstützt die ObjectDataSource, an die gridView gebunden ist (CategoriesDataSource), das Löschen nicht.

Um dies zu beheben, klicken Sie im Smarttag ObjectDataSource auf die Option Datenquelle konfigurieren, um den Assistenten zu starten. Der erste Bildschirm zeigt, dass ObjectDataSource für die Verwendung mit der CategoriesBLL -Klasse konfiguriert ist. Klicken Sie auf Weiter. Derzeit werden nur die ObjectDataSource-Eigenschaften InsertMethod und SelectMethod angegeben. Der Assistent hat die Dropdownlisten auf den Registerkarten UPDATE und DELETE jedoch automatisch mit den UpdateCategory Methoden und DeleteCategory ausgefüllt. Dies liegt daran, dass wir in der CategoriesBLL -Klasse diese Methoden mit als DataObjectMethodAttribute Standardmethoden zum Aktualisieren und Löschen markiert haben.

Legen Sie vorerst die Dropdownliste UPDATE-Registerkarten auf (Keine) fest, aber lassen Sie die Dropdownliste DELETE-Registerkarten auf DeleteCategoryfestgelegt. Wir kehren zu diesem Assistenten in Schritt 6 zurück, um Updateunterstützung hinzuzufügen.

Konfigurieren der ObjectDataSource für die Verwendung der DeleteCategory-Methode

Abbildung 4: Konfigurieren der ObjectDataSource für die Verwendung der DeleteCategory -Methode (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Nach Abschluss des Assistenten fragt Visual Studio möglicherweise, ob Sie Felder und Schlüssel aktualisieren möchten, wodurch die Datenwebsteuerelementfelder neu generiert werden. Wählen Sie Nein aus, da durch Auswahl von Ja alle Feldanpassungen überschrieben werden, die Sie möglicherweise vorgenommen haben.

Die ObjectDataSource enthält nun einen -Wert für seine DeleteMethod -Eigenschaft sowie einen DeleteParameter. Wenn Sie den Assistenten zum Angeben der Methoden verwenden, legt Visual Studio die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf fest original_{0}, was Probleme mit den Aufrufen der Update- und Löschmethode verursacht. Löschen Sie daher diese Eigenschaft vollständig, oder setzen Sie sie auf den Standardwert zurück {0}. Wenn Sie Ihren Arbeitsspeicher für diese ObjectDataSource-Eigenschaft aktualisieren müssen, lesen Sie das Tutorial Eine Übersicht über das Einfügen, Aktualisieren und Löschen von Daten .

Nachdem Sie den Assistenten abgeschlossen und den OldValuesParameterFormatStringbehoben haben, sollte das deklarative Markup des ObjectDataSource-Objekts in etwa wie folgt aussehen:

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
    OldValuesParameterFormatString="{0}" SelectMethod="GetCategories" 
    TypeName="CategoriesBLL" InsertMethod="InsertWithPicture" 
    DeleteMethod="DeleteCategory">
    <InsertParameters>
        <asp:Parameter Name="categoryName" Type="String" />
        <asp:Parameter Name="description" Type="String" />
        <asp:Parameter Name="brochurePath" Type="String" />
        <asp:Parameter Name="picture" Type="Object" />
    </InsertParameters>
    <DeleteParameters>
        <asp:Parameter Name="categoryID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Fügen Sie nach dem Konfigurieren der ObjectDataSource Löschfunktionen zu GridView hinzu, indem Sie das Kontrollkästchen Löschen aktivieren im Smarttag von GridView aktivieren. Dadurch wird dem GridView-Objekt ein CommandField hinzugefügt, dessen ShowDeleteButton Eigenschaft auf truefestgelegt ist.

Aktivieren der Unterstützung für das Löschen in GridView

Abbildung 5: Aktivieren der Unterstützung für das Löschen in GridView (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nehmen Sie sich einen Moment Zeit, um die Löschfunktion zu testen. Es gibt einen Fremdschlüssel zwischen den Products Tabellen s CategoryID und den Categories Tabellen s CategoryID, sodass Sie eine Ausnahme zur Verletzung der Fremdschlüsseleinschränkung erhalten, wenn Sie versuchen, eine der ersten acht Kategorien zu löschen. Um diese Funktionalität zu testen, fügen Sie eine neue Kategorie hinzu, die sowohl eine Broschüre als auch ein Bild bereitstellt. Meine Testkategorie, die in Abbildung 6 dargestellt ist, enthält eine Testbroschürendatei namens Test.pdf und ein Testbild. Abbildung 7 zeigt gridView, nachdem die Testkategorie hinzugefügt wurde.

Hinzufügen einer Testkategorie mit einer Broschüre und einem Bild

Abbildung 6: Hinzufügen einer Testkategorie mit einer Broschüre und einem Bild (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach dem Einfügen der Testkategorie wird sie in GridView angezeigt.

Abbildung 7: Nach dem Einfügen der Testkategorie wird sie in GridView angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Aktualisieren Sie in Visual Studio die Projektmappen-Explorer. Im Ordner Test.pdf sollte nun eine neue Datei ~/Brochures angezeigt werden (siehe Abbildung 8).

Klicken Sie als Nächstes in der Zeile Testkategorie auf den Link Löschen, sodass die Seite postback und die Methode der CategoriesBLLDeleteCategory Klasse ausgelöst wird. Dadurch wird die DAL-Methode Delete aufgerufen, sodass die entsprechende DELETE Anweisung an die Datenbank gesendet wird. Die Daten werden dann an gridView gesendet, und das Markup wird zurück an den Client gesendet, wobei die Testkategorie nicht mehr vorhanden ist.

Während der Löschworkflow den Datensatz Testkategorie erfolgreich aus der Categories Tabelle entfernt hat, wurde die Broschürendatei nicht aus dem Dateisystem des Webservers entfernt. Aktualisieren Sie die Projektmappen-Explorer, und Sie sehen, dass sich Test.pdf noch im ~/Brochures Ordner befindet.

Die Test.pdf-Datei wurde nicht aus dem Dateisystem des Webservers gelöscht.

Abbildung 8: Die Test.pdf Datei wurde nicht aus dem Dateisystem des Webservers gelöscht.

Schritt 5: Entfernen der Broschürendatei der gelöschten Kategorie

Einer der Nachteile beim Speichern von Binärdaten außerhalb der Datenbank besteht darin, dass zusätzliche Schritte ausgeführt werden müssen, um diese Dateien zu sauber, wenn der zugehörige Datenbankdatensatz gelöscht wird. GridView und ObjectDataSource stellen Ereignisse bereit, die sowohl vor als auch nach der Ausführung des Löschbefehls ausgelöst werden. Wir müssen tatsächlich Ereignishandler für die Ereignisse vor und nach der Aktion erstellen. Bevor der Categories Datensatz gelöscht wird, müssen wir den Pfad der PDF-Datei bestimmen, aber wir möchten die PDF-Datei nicht löschen, bevor die Kategorie gelöscht wird, falls es eine Ausnahme gibt und die Kategorie nicht gelöscht wird.

Das GridView-Ereignis RowDeleting wird ausgelöst, bevor der ObjectDataSource-Befehl delete aufgerufen wurde, während das RowDeleted Ereignis danach ausgelöst wird. Erstellen Sie Ereignishandler für diese beiden Ereignisse mit dem folgenden Code:

// A page variable to "remember" the deleted category's BrochurePath value 
string deletedCategorysPdfPath = null;
protected void Categories_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    // Determine the PDF path for the category being deleted...
    int categoryID = Convert.ToInt32(e.Keys["CategoryID"]);
    CategoriesBLL categoryAPI = new CategoriesBLL();
    Northwind.CategoriesDataTable categories = 
        categoryAPI.GetCategoryByCategoryID(categoryID);
    Northwind.CategoriesRow category = categories[0];
    if (category.IsBrochurePathNull())
        deletedCategorysPdfPath = null;
    else
        deletedCategorysPdfPath = category.BrochurePath;
}
protected void Categories_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
    // Delete the brochure file if there were no problems deleting the record
    if (e.Exception == null)
    {
        // Is there a file to delete?
        if (deletedCategorysPdfPath != null)
        {
            System.IO.File.Delete(Server.MapPath(deletedCategorysPdfPath));
        }
    }
}

RowDeleting Im Ereignishandler wird die der CategoryID zu löschenden Zeile aus der GridView-Auflistung DataKeys abgerufen, auf die in diesem Ereignishandler über die e.Keys Auflistung zugegriffen werden kann. Als Nächstes wird die CategoriesBLL Klasse s GetCategoryByCategoryID(categoryID) aufgerufen, um Informationen über den zu löschenden Datensatz zurückzugeben. Wenn das zurückgegebene CategoriesDataRow Objekt über einen Nicht-WertNULL``BrochurePath verfügt, wird es in der Seitenvariablen deletedCategorysPdfPath gespeichert, sodass die Datei im RowDeleted Ereignishandler gelöscht werden kann.

Hinweis

Anstatt die Details für den BrochurePath Datensatz abzurufen, der CategoriesRowDeleting im Ereignishandler gelöscht wird, hätten wir alternativ der GridView-Eigenschaft DataKeyNames hinzufügen BrochurePath und über die e.Keys Auflistung auf den Wert des Datensatzes zugreifen können. Dies würde die Größe des Ansichtszustands von GridView geringfügig erhöhen, aber die menge des benötigten Codes reduzieren und eine Reise in die Datenbank speichern.

Nachdem der zugrunde liegende Löschbefehl ObjectDataSource aufgerufen wurde, wird der GridView-Ereignishandler RowDeleted ausgelöst. Wenn es keine Ausnahmen beim Löschen der Daten gab und es einen Wert für deletedCategorysPdfPathgibt, wird die PDF aus dem Dateisystem gelöscht. Beachten Sie, dass dieser zusätzliche Code nicht erforderlich ist, um die Binärdaten der Kategorie zu sauber, die dem Bild zugeordnet sind. Das liegt daran, dass die Bilddaten direkt in der Datenbank gespeichert werden, sodass durch das Löschen der Categories Zeile auch die Bilddaten dieser Kategorie gelöscht werden.

Nachdem Sie die beiden Ereignishandler hinzugefügt haben, führen Sie diesen Testfall erneut aus. Beim Löschen der Kategorie wird auch die zugehörige PDF-Datei gelöscht.

Das Aktualisieren eines vorhandenen Datensatzes mit zugeordneten Binärdaten stellt einige interessante Herausforderungen bereit. Der Rest dieses Tutorials befasst sich mit dem Hinzufügen von Updatefunktionen zur Broschüre und dem Bild. In Schritt 6 werden Techniken zum Aktualisieren der Broschüreninformationen untersucht, während In Schritt 7 das Aktualisieren des Bilds untersucht wird.

Schritt 6: Aktualisieren einer Kategoriebroschüre

Wie im Tutorial Eine Übersicht über das Einfügen, Aktualisieren und Löschen von Daten erläutert, bietet GridView integrierte Bearbeitungsunterstützung auf Zeilenebene, die durch das Aktivieren eines Kontrollkästchens implementiert werden kann, wenn die zugrunde liegende Datenquelle entsprechend konfiguriert ist. Derzeit ist die CategoriesDataSource ObjectDataSource noch nicht so konfiguriert, dass sie Aktualisierungsunterstützung enthält. Fügen Sie dies also hinzu.

Klicken Sie im ObjectDataSource-Assistenten auf den Link Datenquelle konfigurieren, und fahren Sie mit dem zweiten Schritt fort. Aufgrund der DataObjectMethodAttribute in CategoriesBLLsollte die Dropdownliste UPDATE automatisch mit der Überladung aufgefüllt werden, die UpdateCategory vier Eingabeparameter akzeptiert (für alle Spalten, aber Picture). Ändern Sie dies, sodass die Überladung mit fünf Parametern verwendet wird.

Konfigurieren der ObjectDataSource für die Verwendung der UpdateCategory-Methode, die einen Parameter für Picture enthält

Abbildung 9: Konfigurieren der ObjectDataSource für die Verwendung der Methode, die UpdateCategory einen Parameter enthält Picture (Klicken Sie, um das bild in voller Größe anzuzeigen)

Die ObjectDataSource enthält nun einen Wert für ihre UpdateMethod Eigenschaft sowie entsprechende UpdateParameter s. Wie in Schritt 4 beschrieben, legt Visual Studio die ObjectDataSource-Eigenschaft OldValuesParameterFormatString bei Verwendung des Assistenten Datenquelle konfigurieren auf original_{0} fest. Dies führt zu Problemen mit den Aufrufen der Update- und Löschmethoden. Löschen Sie diese Eigenschaft daher entweder vollständig, oder setzen Sie sie auf den Standardwert zurück {0}.

Nachdem Sie den Assistenten abgeschlossen und den OldValuesParameterFormatStringbehoben haben, sollte das deklarative Markup des ObjectDataSource-Objekts wie folgt aussehen:

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
    OldValuesParameterFormatString="{0}" SelectMethod="GetCategories" 
    TypeName="CategoriesBLL" InsertMethod="InsertWithPicture" 
    DeleteMethod="DeleteCategory" UpdateMethod="UpdateCategory">
    <InsertParameters>
        <asp:Parameter Name="categoryName" Type="String" />
        <asp:Parameter Name="description" Type="String" />
        <asp:Parameter Name="brochurePath" Type="String" />
        <asp:Parameter Name="picture" Type="Object" />
    </InsertParameters>
    <DeleteParameters>
        <asp:Parameter Name="categoryID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="categoryName" Type="String" />
        <asp:Parameter Name="description" Type="String" />
        <asp:Parameter Name="brochurePath" Type="String" />
        <asp:Parameter Name="picture" Type="Object" />
        <asp:Parameter Name="categoryID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Um die integrierten Bearbeitungsfeatures von GridView zu aktivieren, aktivieren Sie die Option Bearbeitung aktivieren im Smarttag von GridView. Dadurch wird die CommandField-Eigenschaft ShowEditButton auf truefestgelegt, was zum Hinzufügen einer Schaltfläche Bearbeiten (sowie der Schaltflächen Aktualisieren und Abbrechen für die zu bearbeitende Zeile) führt.

Konfigurieren der GridView für die Unterstützung der Bearbeitung

Abbildung 10: Konfigurieren der GridView für die Unterstützung der Bearbeitung (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Besuchen Sie die Seite über einen Browser, und klicken Sie auf eine der Schaltflächen Bearbeiten in der Zeile. Die CategoryName BoundFields und Description werden als Textfelder gerendert. Dem BrochurePath TemplateField fehlt ein EditItemTemplate, sodass weiterhin ein Link zur Broschüre angezeigt ItemTemplate wird. ImageField Picture wird als TextBox gerendert, dessen Text Eigenschaft der Wert des ImageField-Werts DataImageUrlField zugewiesen wird, in diesem Fall CategoryID.

Der GridView fehlt eine Bearbeitungsschnittstelle für BrochurePath

Abbildung 11: Die GridView verfügt über keine Bearbeitungsschnittstelle für BrochurePath (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Anpassen derBrochurePathBearbeitungsschnittstelle von s

Wir müssen eine Bearbeitungsschnittstelle für TemplateField erstellen, die BrochurePath dem Benutzer folgendes ermöglicht:

  • Lassen Sie die Broschüre der Kategorie unverändert.
  • Aktualisieren Sie die Broschüre der Kategorie, indem Sie eine neue Broschüre hochladen, oder
  • Entfernen Sie die Broschüre der Kategorie vollständig (falls die Kategorie keine zugehörige Broschüre mehr enthält).

Wir müssen auch die Bearbeitungsoberfläche von Picture ImageField aktualisieren, dies wird jedoch in Schritt 7 beschrieben.

Klicken Sie im Smarttag von GridView auf den Link Vorlagen bearbeiten, und wählen Sie in der BrochurePath Dropdownliste die TemplateField s EditItemTemplate aus. Fügen Sie dieser Vorlage ein RadioButtonList-Websteuerelement hinzu, und legen Sie dessen ID Eigenschaft auf BrochureOptions und seine AutoPostBack Eigenschaft auf fest true. Klicken Sie in der Eigenschaftenfenster auf die Auslassungspunkte in der Items Eigenschaft, wodurch die ListItem Sammlung Editor angezeigt wird. Fügen Sie die folgenden drei Optionen mit Value s 1, 2 bzw. 3 hinzu:

  • Aktuelle Broschüre verwenden
  • Aktuelle Broschüre entfernen
  • Neue Broschüre hochladen

Legen Sie die erste ListItem s-Eigenschaft Selected auf fest true.

Hinzufügen von drei ListItems zur RadioButtonList

Abbildung 12: Hinzufügen von drei ListItem s zur RadioButtonList

Fügen Sie unterhalb der RadioButtonList ein FileUpload-Steuerelement mit dem Namen hinzu BrochureUpload. Legen Sie die zugehörige Visible-Eigenschaft auf false fest.

Hinzufügen eines RadioButtonList- und FileUpload-Steuerelements zur EditItemTemplate

Abbildung 13: Hinzufügen eines RadioButtonList- und FileUpload-Steuerelements zum (Klicken, um dasEditItemTemplate bild in voller Größe anzuzeigen)

Diese RadioButtonList stellt die drei Optionen für den Benutzer bereit. Die Idee besteht darin, dass das FileUpload-Steuerelement nur angezeigt wird, wenn die letzte Option Neue Broschüre hochladen ausgewählt ist. Erstellen Sie dazu einen Ereignishandler für das RadioButtonList-Ereignis SelectedIndexChanged , und fügen Sie den folgenden Code hinzu:

protected void BrochureOptions_SelectedIndexChanged(object sender, EventArgs e)
{
    // Get a reference to the RadioButtonList and its Parent
    RadioButtonList BrochureOptions = (RadioButtonList)sender;
    Control parent = BrochureOptions.Parent;
    // Now use FindControl("controlID") to get a reference of the 
    // FileUpload control
    FileUpload BrochureUpload = 
        (FileUpload)parent.FindControl("BrochureUpload");
    // Only show BrochureUpload if SelectedValue = "3"
    BrochureUpload.Visible = (BrochureOptions.SelectedValue == "3");
}

Da sich die Steuerelemente RadioButtonList und FileUpload in einer Vorlage befinden, müssen wir ein wenig Code schreiben, um programmgesteuert auf diese Steuerelemente zuzugreifen. Dem SelectedIndexChanged Ereignishandler wird ein Verweis auf die RadioButtonList im sender Eingabeparameter übergeben. Um das FileUpload-Steuerelement abzurufen, müssen wir das übergeordnete Steuerelement des RadioButtonList-Steuerelements abrufen und die FindControl("controlID") -Methode von dort verwenden. Sobald ein Verweis auf das RadioButtonList- und das FileUpload-Steuerelement vorhanden ist, wird die Eigenschaft des FileUpload-Steuerelements Visible nur dann auf true festgelegt, wenn die RadioButtonList s SelectedValue gleich 3 ist, was für die Value Neue Broschüre ListItemhochladen ist.

Nehmen Sie sich einen Moment Zeit, um die Bearbeitungsschnittstelle zu testen. Klicken Sie für eine Zeile auf die Schaltfläche Bearbeiten. Zunächst sollte die Option Aktuelle Broschüre verwenden ausgewählt sein. Das Ändern des ausgewählten Indexes führt zu einem Postback. Wenn die dritte Option ausgewählt ist, wird das FileUpload-Steuerelement angezeigt, andernfalls wird es ausgeblendet. Abbildung 14 zeigt die Bearbeitungsoberfläche, wenn zuerst auf die Schaltfläche Bearbeiten geklickt wird. Abbildung 15 zeigt die Schnittstelle, nachdem die Option Neue Broschüre hochladen ausgewählt ist.

Zunächst ist die Option Aktuelle Broschüre verwenden ausgewählt.

Abbildung 14: Zunächst ist die Option Aktuelle Broschüre verwenden ausgewählt (Klicken Sie, um das bild in voller Größe anzuzeigen)

Wenn Sie die Option Neue Broschüre hochladen auswählen, wird das DateiUpload-Steuerelement angezeigt.

Abbildung 15: Auswählen der Option Neue Broschüre hochladen zeigt das DateiUpload-Steuerelement an (Klicken, um das bild in voller Größe anzuzeigen)

Speichern der Broschürendatei und Aktualisieren derBrochurePathSpalte

Wenn auf die Schaltfläche "Aktualisieren" von GridView geklickt wird, wird das RowUpdating -Ereignis ausgelöst. Der Befehl "ObjectDataSource update" wird aufgerufen, und dann wird das GridView-Ereignis RowUpdated ausgelöst. Wie beim Löschworkflow müssen wir Ereignishandler für beide Ereignisse erstellen. RowUpdating Im Ereignishandler müssen wir anhand SelectedValue der BrochureOptions der RadioButtonList bestimmen, welche Aktion ausgeführt werden soll:

  • SelectedValue Wenn 1 ist, möchten wir weiterhin dieselbe BrochurePath Einstellung verwenden. Daher müssen wir den ObjectDataSource-Parameter brochurePath auf den vorhandenen BrochurePath Wert des zu aktualisierenden Datensatzes festlegen. Der ObjectDataSource-Parameter brochurePath kann mit e.NewValues["brochurePath"] = valuefestgelegt werden.
  • SelectedValue Wenn 2 ist, möchten wir den Wert des Datensatzes BrochurePath auf NULLfestlegen. Dies kann durch Festlegen des ObjectDataSource-Parameters brochurePath auf Nothingerreicht werden, was dazu führt, dass eine Datenbank NULL in der UPDATE -Anweisung verwendet wird. Wenn eine Broschürendatei vorhanden ist, die entfernt wird, müssen wir die vorhandene Datei löschen. Wir möchten dies jedoch nur tun, wenn das Update abgeschlossen wird, ohne eine Ausnahme auszulösen.
  • SelectedValue Wenn 3 ist, möchten wir sicherstellen, dass der Benutzer eine PDF-Datei hochgeladen hat, speichern sie dann im Dateisystem und aktualisieren den Spaltenwert des DatensatzesBrochurePath. Wenn außerdem eine Broschürendatei vorhanden ist, die ersetzt wird, müssen wir die vorherige Datei löschen. Wir möchten dies jedoch nur tun, wenn das Update abgeschlossen wird, ohne eine Ausnahme auszulösen.

Die schritte, die ausgeführt werden müssen, wenn radioButtonList s SelectedValue 3 ist, sind praktisch identisch mit denen, die vom DetailsView s-Ereignishandler ItemInserting verwendet werden. Dieser Ereignishandler wird ausgeführt, wenn ein neuer Kategoriedatensatz aus dem DetailsView-Steuerelement hinzugefügt wird, das wir im vorherigen Tutorial hinzugefügt haben. Daher ist es erforderlich, diese Funktionalität in separate Methoden umzugestalten. Insbesondere habe ich die allgemeine Funktionalität in zwei Methoden verschoben:

  • ProcessBrochureUpload(FileUpload, out bool)akzeptiert als Eingabe ein FileUpload-Steuerelement instance und einen booleschen Ausgabewert, der angibt, ob der Lösch- oder Bearbeitungsvorgang fortgesetzt werden soll oder ob er aufgrund eines Überprüfungsfehlers abgebrochen werden soll. Diese Methode gibt den Pfad zur gespeicherten Datei oder null zurück, wenn keine Datei gespeichert wurde.
  • DeleteRememberedBrochurePath löscht die Datei, die vom Pfad in der Seitenvariablen deletedCategorysPdfPath angegeben wird, wenn deletedCategorysPdfPath nicht nullist.

Der Code für diese beiden Methoden folgt. Beachten Sie die Ähnlichkeit zwischen ProcessBrochureUpload und dem DetailsView-Ereignishandler ItemInserting aus dem vorherigen Tutorial. In diesem Tutorial habe ich die Ereignishandler von DetailsView aktualisiert, um diese neuen Methoden zu verwenden. Laden Sie den diesem Tutorial zugeordneten Code herunter, um die Änderungen an den Ereignishandlern von DetailsView anzuzeigen.

private string ProcessBrochureUpload
    (FileUpload BrochureUpload, out bool CancelOperation)
{
    CancelOperation = false;    // by default, do not cancel operation
    if (BrochureUpload.HasFile)
    {
        // Make sure that a PDF has been uploaded
        if (string.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName), 
            ".pdf", true) != 0)
        {
            UploadWarning.Text = 
                "Only PDF documents may be used for a category's brochure.";
            UploadWarning.Visible = true;
            CancelOperation = true;
            return null;
        }
        const string BrochureDirectory = "~/Brochures/";
        string brochurePath = BrochureDirectory + BrochureUpload.FileName;
        string fileNameWithoutExtension = 
            System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName);
        int iteration = 1;
        while (System.IO.File.Exists(Server.MapPath(brochurePath)))
        {
            brochurePath = string.Concat(BrochureDirectory, fileNameWithoutExtension, 
                "-", iteration, ".pdf");
            iteration++;
        }
        // Save the file to disk and set the value of the brochurePath parameter
        BrochureUpload.SaveAs(Server.MapPath(brochurePath));
        return brochurePath;
    }
    else
    {
        // No file uploaded
        return null;
    }
}
private void DeleteRememberedBrochurePath()
{
    // Is there a file to delete?
    if (deletedCategorysPdfPath != null)
    {
        System.IO.File.Delete(Server.MapPath(deletedCategorysPdfPath));
    }
}

Die GridView- RowUpdating und RowUpdated -Ereignishandler verwenden die ProcessBrochureUpload Methoden und DeleteRememberedBrochurePath , wie im folgenden Code gezeigt:

protected void Categories_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    // Reference the RadioButtonList
    RadioButtonList BrochureOptions = 
        (RadioButtonList)Categories.Rows[e.RowIndex].FindControl("BrochureOptions");
    // Get BrochurePath information about the record being updated
    int categoryID = Convert.ToInt32(e.Keys["CategoryID"]);
    CategoriesBLL categoryAPI = new CategoriesBLL();
    Northwind.CategoriesDataTable categories = 
        categoryAPI.GetCategoryByCategoryID(categoryID);
    Northwind.CategoriesRow category = categories[0];
    if (BrochureOptions.SelectedValue == "1")
    {
        // Use current value for BrochurePath
        if (category.IsBrochurePathNull())
            e.NewValues["brochurePath"] = null;
        else
            e.NewValues["brochurePath"] = category.BrochurePath;
    }
    else if (BrochureOptions.SelectedValue == "2")
    {
        // Remove the current brochure (set it to NULL in the database)
        e.NewValues["brochurePath"] = null;
    }
    else if (BrochureOptions.SelectedValue == "3")
    {
        // Reference the BrochurePath FileUpload control
        FileUpload BrochureUpload = 
            (FileUpload)Categories.Rows[e.RowIndex].FindControl("BrochureUpload");
        // Process the BrochureUpload
        bool cancelOperation = false;
        e.NewValues["brochurePath"] = 
            ProcessBrochureUpload(BrochureUpload, out cancelOperation);
        e.Cancel = cancelOperation;
    }
    else
    {
        // Unknown value!
        throw new ApplicationException(
            string.Format("Invalid BrochureOptions value, {0}", 
                BrochureOptions.SelectedValue));
    }
    if (BrochureOptions.SelectedValue == "2" || 
        BrochureOptions.SelectedValue == "3")
    {
        // "Remember" that we need to delete the old PDF file
        if (category.IsBrochurePathNull())
            deletedCategorysPdfPath = null;
        else
            deletedCategorysPdfPath = category.BrochurePath;
    }
}
protected void Categories_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
    // If there were no problems and we updated the PDF file, 
    // then delete the existing one
    if (e.Exception == null)
    {
        DeleteRememberedBrochurePath();
    }
}

Beachten Sie, wie der RowUpdating Ereignishandler eine Reihe von bedingten Anweisungen verwendet, um die entsprechende Aktion basierend auf dem Eigenschaftswert von BrochureOptions RadioButtonList SelectedValue auszuführen.

Mit diesem Code können Sie eine Kategorie bearbeiten und ihre aktuelle Broschüre verwenden, keine Broschüre verwenden oder eine neue hochladen. Probieren Sie es aus. Legen Sie Haltepunkte in den RowUpdating Ereignishandlern und RowUpdated fest, um einen Überblick über den Workflow zu erhalten.

Schritt 7: Hochladen eines neuen Bilds

Die Picture Bearbeitungsschnittstelle von ImageField wird als Textfeld gerendert, das mit dem Wert aus der DataImageUrlField -Eigenschaft aufgefüllt wird. Während des Bearbeitungsworkflows übergibt GridView einen Parameter an objectDataSource mit dem Parameternamen des Werts der ImageField-Eigenschaft DataImageUrlField und dem Parameter s-Wert, der in das Textfeld in der Bearbeitungsoberfläche eingegeben wurde. Dieses Verhalten eignet sich, wenn das Bild als Datei im Dateisystem gespeichert wird und die DataImageUrlField die vollständige URL des Bilds enthält. Unter solchen Umständen zeigt die Bearbeitungsoberfläche die BILD-URL im Textfeld an, die der Benutzer ändern und in der Datenbank gespeichert haben kann. Zugegeben, diese Standardschnittstelle ermöglicht es dem Benutzer nicht, ein neues Bild hochzuladen, aber er ermöglicht es ihm, die URL des Bilds vom aktuellen Wert in einen anderen zu ändern. Für dieses Tutorial reicht die Standardbearbeitungsschnittstelle von ImageField jedoch nicht aus, da die Picture Binärdaten direkt in der Datenbank gespeichert werden und die DataImageUrlField -Eigenschaft nur den CategoryIDenthält.

Um besser zu verstehen, was in unserem Tutorial geschieht, wenn ein Benutzer eine Zeile mit einem ImageField bearbeitet, betrachten Sie das folgende Beispiel: Ein Benutzer bearbeitet eine Zeile mit CategoryID 10, wodurch imageField Picture als Textfeld mit dem Wert 10 gerendert wird. Angenommen, der Benutzer ändert den Wert in diesem Textfeld in 50 und klickt auf die Schaltfläche Aktualisieren. Es erfolgt ein Postback, und GridView erstellt zunächst einen Parameter namens CategoryID mit dem Wert 50. Bevor GridView jedoch diesen Parameter (und die CategoryName Parameter und Description ) sendet, fügt es die Werte aus der DataKeys Auflistung hinzu. Daher überschreibt er den CategoryID Parameter mit dem zugrunde liegenden CategoryID Wert der aktuellen Zeile( 10). Kurz gesagt, die Bearbeitungsoberfläche von ImageField hat keine Auswirkungen auf den Bearbeitungsworkflow für dieses Tutorial, da die Namen der ImageField-Eigenschaft DataImageUrlField und des Rasterwerts DataKey eins sind.

ImageField erleichtert zwar die Anzeige eines Bilds basierend auf Datenbankdaten, aber wir möchten kein Textfeld in der Bearbeitungsoberfläche bereitstellen. Stattdessen möchten wir ein FileUpload-Steuerelement anbieten, das der Endbenutzer verwenden kann, um das Bild der Kategorie zu ändern. BrochurePath Im Gegensatz zum Wert haben wir uns für diese Tutorials entschieden, dass jede Kategorie ein Bild haben muss. Daher muss der Benutzer nicht angeben lassen, dass kein zugeordnetes Bild vorhanden ist, das der Benutzer entweder ein neues Bild hochladen oder das aktuelle Bild unverändert belassen kann.

Um die Bearbeitungsoberfläche von ImageField anzupassen, müssen wir sie in ein TemplateField konvertieren. Klicken Sie im Smarttag von GridView auf den Link Spalten bearbeiten, wählen Sie imageField aus, und klicken Sie auf den Link Dieses Feld in ein TemplateField konvertieren.

Konvertieren des ImageField in ein TemplateField

Abbildung 16: Konvertieren des ImageField in ein TemplateField

Wenn Sie imageField auf diese Weise in ein TemplateField konvertieren, wird ein TemplateField mit zwei Vorlagen generiert. Wie die folgende deklarative Syntax zeigt, enthält die ItemTemplate ein Image Web-Steuerelement, dessen ImageUrl Eigenschaft mithilfe der Datenbindungssyntax basierend auf den ImageField-Eigenschaften DataImageUrlField und DataImageUrlFormatString zugewiesen wird. EditItemTemplate enthält ein TextBox-Objekt, dessen Text Eigenschaft an den von der DataImageUrlField -Eigenschaft angegebenen Wert gebunden ist.

<asp:TemplateField>
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server" 
            Text='<%# Eval("CategoryID") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Image ID="Image1" runat="server" 
            ImageUrl='<%# Eval("CategoryID", 
                "DisplayCategoryPicture.aspx?CategoryID={0}") %>' />
    </ItemTemplate>
</asp:TemplateField>

Wir müssen aktualisieren EditItemTemplate , um ein FileUpload-Steuerelement zu verwenden. Klicken Sie im Smarttag von GridView auf den Link Vorlagen bearbeiten, und wählen Sie dann die Picture TemplateFields EditItemTemplate aus der Dropdownliste aus. In der Vorlage sollte ein TextBox-Objekt angezeigt werden. Ziehen Sie als Nächstes ein FileUpload-Steuerelement aus der Toolbox in die Vorlage, und legen Sie dessen ID auf fest PictureUpload. Fügen Sie außerdem den Text hinzu, um das Kategoriebild zu ändern, geben Sie ein neues Bild an. Um das Bild der Kategorie unverändert zu lassen, lassen Sie das Feld auch der Vorlage leer.

Hinzufügen eines FileUpload-Steuerelements zu EditItemTemplate

Abbildung 17: Hinzufügen eines FileUpload-Steuerelements zum EditItemTemplate -Steuerelement (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nachdem Sie die Bearbeitungsoberfläche angepasst haben, zeigen Sie Ihren Fortschritt in einem Browser an. Wenn Sie eine Zeile im schreibgeschützten Modus anzeigen, wird das Bild der Kategorie wie zuvor angezeigt. Wenn Sie jedoch auf die Schaltfläche Bearbeiten klicken, wird die Bildspalte mit einem FileUpload-Steuerelement als Text gerendert.

Die Bearbeitungsschnittstelle enthält ein FileUpload-Steuerelement.

Abbildung 18: Die Bearbeitungsschnittstelle enthält ein FileUpload-Steuerelement (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Denken Sie daran, dass objectDataSource so konfiguriert ist, dass die Methode s UpdateCategory der CategoriesBLL Klasse aufgerufen wird, die die Binärdaten für das Bild als byte Array als Eingabe akzeptiert. Wenn dieses Array jedoch über einen null Wert verfügt, wird die alternative UpdateCategory Überladung aufgerufen, die die SQL-Anweisung UPDATE ausgibt, die die Picture Spalte nicht ändert, wodurch das aktuelle Bild der Kategorie intakt bleibt. Daher müssen wir im GridView-Ereignishandler RowUpdating programmgesteuert auf das PictureUpload FileUpload-Steuerelement verweisen und ermitteln, ob eine Datei hochgeladen wurde. Wenn ein Wert nicht hochgeladen wurde, möchten wir keinen Wert für den picture Parameter angeben. Wenn eine Datei dagegen im PictureUpload FileUpload-Steuerelement hochgeladen wurde, möchten wir sicherstellen, dass es sich um eine JPG-Datei handelt. Wenn dies der Grund ist, können wir den binären Inhalt über den Parameter an objectDataSource picture senden.

Wie bei dem code, der in Schritt 6 verwendet wird, ist ein Großteil des hier benötigten Codes bereits im Ereignishandler von DetailsView s ItemInserting vorhanden. Daher habe ich die allgemeine Funktionalität in eine neue Methode umgestaltet ValidPictureUploadund den ItemInserting Ereignishandler aktualisiert, um diese Methode zu verwenden.

Fügen Sie den folgenden Code am Anfang des GridView-Ereignishandlers hinzu RowUpdating . Es ist wichtig, dass dieser Code vor den Code kommt, der die Broschürendatei speichert, da wir die Broschüre nicht im Dateisystem des Webservers speichern möchten, wenn eine ungültige Bilddatei hochgeladen wird.

// Reference the PictureUpload FileUpload
FileUpload PictureUpload = 
    (FileUpload)Categories.Rows[e.RowIndex].FindControl("PictureUpload");
if (PictureUpload.HasFile)
{
    // Make sure the picture upload is valid
    if (ValidPictureUpload(PictureUpload))
    {
        e.NewValues["picture"] = PictureUpload.FileBytes;
    }
    else
    {
        // Invalid file upload, cancel update and exit event handler
        e.Cancel = true;
        return;
    }
}

Die ValidPictureUpload(FileUpload) -Methode verwendet ein FileUpload-Steuerelement als einzigen Eingabeparameter und überprüft die hochgeladene Dateierweiterung, um sicherzustellen, dass es sich bei der hochgeladenen Datei um eine JPG-Datei handelt. Sie wird nur aufgerufen, wenn eine Bilddatei hochgeladen wird. Wenn keine Datei hochgeladen wird, ist der parameter picture nicht festgelegt und verwendet daher den Standardwert .null Wenn ein Bild hochgeladen wurde und ValidPictureUpload zurückgibt true, werden dem picture Parameter die Binärdaten des hochgeladenen Bilds zugewiesen. Wenn die Methode zurückgibt false, wird der Aktualisierungsworkflow abgebrochen und der Ereignishandler beendet.

Der ValidPictureUpload(FileUpload) Methodencode, der aus dem Ereignishandler von DetailsView ItemInserting umgestaltet wurde, folgt:

private bool ValidPictureUpload(FileUpload PictureUpload)
{
    // Make sure that a JPG has been uploaded
    if (string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
            ".jpg", true) != 0 &&
        string.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), 
            ".jpeg", true) != 0)
    {
        UploadWarning.Text = 
            "Only JPG documents may be used for a category's picture.";
        UploadWarning.Visible = true;
        return false;
    }
    else
    {
        return true;
    }
}

Schritt 8: Ersetzen der Ursprünglichen Kategorienbilder durch JPGs

Denken Sie daran, dass die ursprünglichen acht Kategorienbilder Bitmapdateien sind, die in einen OLE-Header umschlossen sind. Nachdem wir nun die Funktion zum Bearbeiten eines vorhandenen Datensatzbilds hinzugefügt haben, nehmen Sie sich einen Moment Zeit, um diese Bitmaps durch JPGs zu ersetzen. Wenn Sie die aktuellen Kategoriebilder weiterhin verwenden möchten, können Sie sie in JPGs konvertieren, indem Sie die folgenden Schritte ausführen:

  1. Speichern Sie die Bitmapbilder auf Ihrer Festplatte. Besuchen Sie die UpdatingAndDeleting.aspx Seite in Ihrem Browser, und klicken Sie für jede der ersten acht Kategorien mit der rechten Maustaste auf das Bild, und wählen Sie aus, um das Bild zu speichern.
  2. Öffnen Sie das Bild im Bild-Editor Ihrer Wahl. Sie können z. B. Microsoft Paint verwenden.
  3. Speichern Sie die Bitmap als JPG-Bild.
  4. Aktualisieren Sie das Bild der Kategorie mithilfe der JPG-Datei über die Bearbeitungsoberfläche.

Nach dem Bearbeiten einer Kategorie und dem Hochladen des JPG-Bilds wird das Bild nicht im Browser gerendert, da die DisplayCategoryPicture.aspx Seite die ersten 78 Bytes aus den Bildern der ersten acht Kategorien entfernt. Beheben Sie dies, indem Sie den Code entfernen, der das Strippen des OLE-Headers ausführt. Danach sollte der DisplayCategoryPicture.aspx``Page_Load Ereignishandler nur über den folgenden Code verfügen:

protected void Page_Load(object sender, EventArgs e)
{
    int categoryID = Convert.ToInt32(Request.QueryString["CategoryID"]);
    // Get information about the specified category
    CategoriesBLL categoryAPI = new CategoriesBLL();
    Northwind.CategoriesDataTable categories = _
        categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID);
    Northwind.CategoriesRow category = categories[0];
    // For new categories, images are JPGs...
    
    // Output HTTP headers providing information about the binary data
    Response.ContentType = "image/jpeg";
    // Output the binary data
    Response.BinaryWrite(category.Picture);
}

Hinweis

Die UpdatingAndDeleting.aspx Einfüge- und Bearbeitungsschnittstellen der Seite könnten etwas mehr Arbeit in Anspruch nehmen. Die CategoryName BoundFields und Description in DetailsView und GridView sollten in TemplateFields konvertiert werden. Da CategoryName keine Werte zulässig NULL sind, sollte ein RequiredFieldValidator hinzugefügt werden. Und das Description Textfeld sollte wahrscheinlich in ein mehrzeiliges TextBox-Objekt konvertiert werden. Ich überlasse diese letzten Schliffe als Übung für Sie.

Zusammenfassung

Dieses Tutorial schließt unseren Blick auf die Arbeit mit Binärdaten ab. In diesem tutorial und den vorherigen drei haben wir erfahren, wie Binärdaten im Dateisystem oder direkt in der Datenbank gespeichert werden können. Ein Benutzer stellt dem System Binärdaten zur Verfügung, indem er eine Datei von seiner Festplatte auswählt und auf den Webserver hochlädt, wo sie im Dateisystem gespeichert oder in die Datenbank eingefügt werden kann. ASP.NET 2.0 enthält ein FileUpload-Steuerelement, das die Bereitstellung einer solchen Schnittstelle so einfach macht wie Drag and Drop. Wie jedoch im Tutorial Hochladen von Dateien erwähnt, eignet sich das FileUpload-Steuerelement nur gut für relativ kleine Dateiuploads, idealerweise nicht mehr als ein Megabyte. Außerdem wurde untersucht, wie sie hochgeladene Daten dem zugrunde liegenden Datenmodell zuordnen und wie die Binärdaten aus vorhandenen Datensätzen bearbeitet und gelöscht werden.

In unseren nächsten Tutorials werden verschiedene Caching-Techniken untersucht. Das Zwischenspeichern bietet eine Möglichkeit, die Gesamtleistung einer Anwendung zu verbessern, indem die Ergebnisse teurer Vorgänge abgerufen und an einem Speicherort gespeichert werden, auf den schneller zugegriffen werden kann.

Viel Spaß beim Programmieren!

Zum Autor

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

Besonderen Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüferin für dieses Tutorial war Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.