Freigeben über


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

von Scott Mitchell

PDF herunterladen

In früheren Tutorials haben wir gezeigt, wie das GridView-Steuerelement das Bearbeiten und Löschen von Textdaten vereinfacht. In diesem Tutorial erfahren Sie, wie das GridView-Steuerelement es auch ermöglicht, Binärdaten zu bearbeiten und zu löschen, unabhängig davon, ob diese binären Daten 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 BrochurePath Spalte zur Categories Tabelle hinzugefügt und die Architektur entsprechend aktualisiert. Wir haben auch Methoden für Datenzugriffsebene und Geschäftslogikebene hinzugefügt, um mit der vorhandenen Picture Spalte der Tabelle Kategorien zu arbeiten, die den binären Inhalt einer Imagedatei enthält. Wir haben Webseiten erstellt, um die Binärdaten in einer GridView einen Downloadlink für die Broschüre mit dem Bild der Kategorie 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, was wir in diesem Tutorial mithilfe der integrierten Bearbeitungs- und Löschfunktionen von GridView durchführen. Beim Bearbeiten einer Kategorie kann der Benutzer optional ein neues Bild hochladen, oder die Kategorie verwendet weiterhin das vorhandene Bild. Für die Broschüre können sie entweder die vorhandene Broschüre verwenden, eine neue Broschüre hochladen oder angeben, dass in der Kategorie keine Broschüre mehr zugeordnet ist. Los geht's!

Schritt 1: Aktualisieren der Datenzugriffsebene

Die DAL verfügt über automatisch generierte InsertMethoden , Update, undDelete, aber diese Methoden wurden basierend auf der CategoriesTableAdapter s-Standard Abfrage 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 erstellen, um der Categories Tabelle einen neuen Datensatz hinzuzufügen, wählen Sie UPDATE 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 nun die SQL-Anweisung UPDATE angeben. Der Assistent schlägt automatisch eine UPDATE Anweisung vor, die der TableAdapter-Standard-Abfrage entspricht (eine Abfrage, die die CategoryNameWerte , Descriptionund BrochurePath aktualisiert). Ändern Sie die Anweisung so, dass die Picture Spalte zusammen mit einem @Picture Parameter enthalten ist, wie folgt:

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

Auf dem letzten Bildschirm des Assistenten werden wir aufgefordert, die neue TableAdapter-Methode zu nennen. Geben Sie ein UpdateWithPicture , und klicken Sie auf Fertig stellen.

Nennen Sie die neue TableAdapter-Methode UpdateWithPicture.

Abbildung 2: Benennen Sie die neue TableAdapter-Methode UpdateWithPicture (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 2: Hinzufügen der Methoden der Geschäftslogikebene

Zusätzlich zum Aktualisieren der DAL müssen wir die BLL so aktualisieren, dass sie Methoden zum Aktualisieren und Löschen einer Kategorie enthält. 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 Function DeleteCategory(ByVal categoryID As Integer) As Boolean
    Dim rowsAffected As Integer = Adapter.Delete(categoryID)
    ' Return true if precisely one row was deleted, otherwise false
    Return rowsAffected = 1
End Function

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 CategoriesTableAdapter akzeptiert, Descriptionund BrochurePath verwendet die automatisch generierte Update Anweisung der Klasse s. Der Grund für die Verwendung von zwei Methoden ist, dass ein Benutzer unter bestimmten Umständen das Bild der Kategorie 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 erfordert eine zusätzliche Reise zur Datenbank, um die Bilddaten für den zu bearbeitenden Datensatz zurückzuholen. Daher wollen 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 erleichtern, fügen Sie der -Klasse zwei Methoden hinzu, die CategoriesBLL beide den Namen haben UpdateCategory. Die erste sollte drei String s, ein Byte Array und ein Integer als Eingabeparameter akzeptieren; der zweite, nur drei String s und ein Integer. Die String Eingabeparameter beziehen sich auf den Namen, die Beschreibung und den Dateipfad der Broschüre, das Byte Array für den binären Inhalt des Kategoriebilds und den IntegerCategoryID des zu aktualisierenden Datensatzes. Beachten Sie, dass die erste Überladung die zweite aufruft, wenn das übergebene Byte Array lautet Nothing:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateCategory(categoryName As String, description As String, _
    brochurePath As String, picture() As Byte, categoryID As Integer) As Boolean
    
    ' If no picture is specified, use other overload
    If picture Is Nothing Then
        Return UpdateCategory(categoryName, description, brochurePath, categoryID)
    End If
    ' Update picture, as well
    Dim rowsAffected As Integer = Adapter.UpdateWithPicture _
        (categoryName, description, brochurePath, picture, categoryID)
    ' Return true if precisely one row was updated, otherwise false
    Return rowsAffected = 1
End Function
<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, True)> _
Public Function UpdateCategory(categoryName As String, description As String, _
    brochurePath As String, categoryID As Integer) As Boolean
    Dim rowsAffected As Integer = Adapter.Update _
        (categoryName, description, brochurePath, categoryID)
    ' Return true if precisely one row was updated, otherwise false
    Return rowsAffected = 1
End Function

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

Im vorherigen Tutorial haben wir eine Seite mit dem Namen UploadInDetailsView.aspx erstellt, die alle Kategorien in einer GridView auflistet und eine DetailsView zum Hinzufügen neuer Kategorien zum System bereitgestellt hat. In diesem Tutorial erweitern wir die GridView um Die Bearbeitungs- und Löschunterstützung. Anstatt weiter von zu UploadInDetailsView.aspxarbeiten, lassen Sie uns stattdessen die Änderungen dieses Tutorials aus demselben Ordner ~/BinaryDataauf der UpdatingAndDeleting.aspx Seite platzieren. Kopieren Sie das deklarative Markup und den Code aus, und fügen Sie ihn in UploadInDetailsView.aspx 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 sein <asp:Content> Element ein. Kopieren Sie auf ähnliche Weise den Code aus der CodeBehind-Klasse der UploadInDetailsView.aspx Seite in UpdatingAndDeleting.aspx.

Kopieren Sie das deklarative Markup aus UploadInDetailsView.aspx

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

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

Schritt 4: Hinzufügen von Unterstützung zum 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 des ObjectDataSource-Smarttags auf die Option Datenquelle konfigurieren, um den Assistenten zu starten. Der erste Bildschirm zeigt, dass die ObjectDataSource für die Verwendung mit der CategoriesBLL -Klasse konfiguriert ist. Klicken Sie auf Weiter. Derzeit werden nur die ObjectDataSource-Eigenschaften InsertMethod und SelectMethod -Eigenschaften angegeben. Der Assistent hat die Dropdownlisten auf den Registerkarten UPDATE und DELETE jedoch automatisch mit den UpdateCategory Methoden und DeleteCategory aufgefüllt. Dies liegt daran, dass wir in der CategoriesBLL -Klasse diese Methoden mit den DataObjectMethodAttribute als Standardmethoden zum Aktualisieren und Löschen markiert haben.

Legen Sie vorerst die Dropdownliste der Registerkarte UPDATE auf (Keine) fest, aber lassen Sie die Dropdownliste DELETE tab s auf DeleteCategoryfestgelegt. Wir kehren zu diesem Assistenten in Schritt 6 zurück, um Aktualisierungsunterstü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 Die Auswahl von Ja alle feldspezifischen Anpassungen überschrieben werden, die Sie möglicherweise vorgenommen haben.

Die ObjectDataSource enthält nun einen Wert für ihre DeleteMethod Eigenschaft sowie einen DeleteParameter. Denken Sie daran, dass Visual Studio bei Verwendung des Assistenten zum Angeben der Methoden die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0}festlegt, was Probleme mit den Aufrufen der Update- und Löschmethode verursacht. Löschen Sie diese Eigenschaft daher entweder 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 .

Nach Abschluss des Assistenten und Korrigieren von OldValuesParameterFormatStringsollte 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">
    <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 der GridView Löschfunktionen hinzu, indem Sie das Kontrollkästchen Löschen aktivieren im Smarttag des GridView-Tags aktivieren. Dadurch wird der GridView-Eigenschaft 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. Zwischen der Tabelle s CategoryID und den ProductsCategories Tabellens CategoryIDbefindet sich ein Fremdschlüssel, 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 In Abbildung 6 gezeigte Testkategorie enthält eine Testbroschürendatei mit dem Namen Test.pdf und ein Testbild. Abbildung 7 zeigt die 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 vollständige Bild anzuzeigen)

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

Abbildung 7: Nach dem Einfügen der Testkategorie wird sie in der GridView angezeigt (klicken, 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
Private deletedCategorysPdfPath As String = Nothing
Protected Sub Categories_RowDeleting(sender As Object, e As GridViewDeleteEventArgs) _
    Handles Categories.RowDeleting
    
    ' Determine the PDF path for the category being deleted...
    Dim categoryID As Integer = Convert.ToInt32(e.Keys("CategoryID"))
    Dim categoryAPI As New CategoriesBLL()
    Dim categoriesData As Northwind.CategoriesDataTable = _
        categoryAPI.GetCategoryByCategoryID(categoryID)
    Dim category As Northwind.CategoriesRow = categoriesData(0)
    If category.IsBrochurePathNull() Then
        deletedCategorysPdfPath = Nothing
    Else
        deletedCategorysPdfPath = category.BrochurePath
    End If
End Sub
Protected Sub Categories_RowDeleted(sender As Object, e As GridViewDeletedEventArgs) _
    Handles Categories.RowDeleted
    
    ' Delete the brochure file if there were no problems deleting the record
    If e.Exception Is Nothing Then
        DeleteRememberedBrochurePath()
    End If
End Sub

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 Sub BrochureOptions_SelectedIndexChanged _
    (sender As Object, e As EventArgs)
    
    ' Get a reference to the RadioButtonList and its Parent
    Dim BrochureOptions As RadioButtonList = _
        CType(sender, RadioButtonList)
    Dim parent As Control = BrochureOptions.Parent
    ' Now use FindControl("controlID") to get a reference of the 
    ' FileUpload control
    Dim BrochureUpload As FileUpload = _
        CType(parent.FindControl("BrochureUpload"), FileUpload)
    ' Only show BrochureUpload if SelectedValue = "3"
    BrochureUpload.Visible = (BrochureOptions.SelectedValue = "3")
End Sub

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 Function ProcessBrochureUpload _
    (BrochureUpload As FileUpload, CancelOperation As Boolean) As String
    
    CancelOperation = False    ' by default, do not cancel operation
    If BrochureUpload.HasFile Then
        ' Make sure that a PDF has been uploaded
        If String.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName), _
            ".pdf", True) <> 0 Then
            
            UploadWarning.Text = _
                "Only PDF documents may be used for a category's brochure."
            UploadWarning.Visible = True
            CancelOperation = True
            Return Nothing
        End If
        Const BrochureDirectory As String = "~/Brochures/"
        Dim brochurePath As String = BrochureDirectory + BrochureUpload.FileName
        Dim fileNameWithoutExtension As String = _
            System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName)
        Dim iteration As Integer = 1
        While System.IO.File.Exists(Server.MapPath(brochurePath))
            brochurePath = String.Concat(BrochureDirectory, _
                fileNameWithoutExtension, "-", iteration, ".pdf")
            iteration += 1
        End While
        ' 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 Nothing
    End If
End Function
Private Sub DeleteRememberedBrochurePath()
    ' Is there a file to delete?
    If deletedCategorysPdfPath IsNot Nothing Then
        System.IO.File.Delete(Server.MapPath(deletedCategorysPdfPath))
    End If
End Sub

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

Protected Sub Categories_RowUpdating _
    (sender As Object, e As GridViewUpdateEventArgs) _
    Handles Categories.RowUpdating
    
    ' Reference the RadioButtonList
    Dim BrochureOptions As RadioButtonList = _
        CType(Categories.Rows(e.RowIndex).FindControl("BrochureOptions"), _
            RadioButtonList)
    ' Get BrochurePath information about the record being updated
    Dim categoryID As Integer = Convert.ToInt32(e.Keys("CategoryID"))
    Dim categoryAPI As New CategoriesBLL()
    Dim categoriesData As Northwind.CategoriesDataTable = _
        categoryAPI.GetCategoryByCategoryID(categoryID)
    Dim category As Northwind.CategoriesRow = categoriesData(0)
    If BrochureOptions.SelectedValue = "1" Then
        ' Use current value for BrochurePath
        If category.IsBrochurePathNull() Then
            e.NewValues("brochurePath") = Nothing
        Else
            e.NewValues("brochurePath") = category.BrochurePath
        End If
    ElseIf BrochureOptions.SelectedValue = "2" Then
        ' Remove the current brochure (set it to NULL in the database)
        e.NewValues("brochurePath") = Nothing
    ElseIf BrochureOptions.SelectedValue = "3" Then
        ' Reference the BrochurePath FileUpload control
        Dim BrochureUpload As FileUpload = _
            CType(categories.Rows(e.RowIndex).FindControl("BrochureUpload"), _
                FileUpload)
        ' Process the BrochureUpload
        Dim cancelOperation As Boolean = False
        e.NewValues("brochurePath") = _
            ProcessBrochureUpload(BrochureUpload, cancelOperation)
        e.Cancel = cancelOperation
    Else
        ' Unknown value!
        Throw New ApplicationException( _
            String.Format("Invalid BrochureOptions value, {0}", _
                BrochureOptions.SelectedValue))
    End If
    If BrochureOptions.SelectedValue = "2" OrElse _
        BrochureOptions.SelectedValue = "3" Then
        
        ' "Remember" that we need to delete the old PDF file
        If (category.IsBrochurePathNull()) Then
            deletedCategorysPdfPath = Nothing
        Else
            deletedCategorysPdfPath = category.BrochurePath
        End If
    End If
End Sub
Protected Sub Categories_RowUpdated _
    (sender As Object, e As GridViewUpdatedEventArgs) _
    Handles Categories.RowUpdated
    
    ' If there were no problems and we updated the PDF file, 
    ' then delete the existing one
    If e.Exception Is Nothing Then
        DeleteRememberedBrochurePath()
    End If
End Sub

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 ist Nothing, 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
Dim PictureUpload As FileUpload = _
    CType(categories.Rows(e.RowIndex).FindControl("PictureUpload"), _
        FileUpload)
If PictureUpload.HasFile Then
    ' Make sure the picture upload is valid
    If ValidPictureUpload(PictureUpload) Then
        e.NewValues("picture") = PictureUpload.FileBytes
    Else
        ' Invalid file upload, cancel update and exit event handler
        e.Cancel = True
        Exit Sub
    End If
End If

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 .Nothing 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 Function ValidPictureUpload(ByVal PictureUpload As FileUpload) As Boolean
    ' Make sure that a JPG has been uploaded
    If String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
        ".jpg", True) <> 0 AndAlso _
        String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName), _
        ".jpeg", True) <> 0 Then
        
        UploadWarning.Text = _
            "Only JPG documents may be used for a category's picture."
        UploadWarning.Visible = True
        Return False
    Else
        Return True
    End If
End Function

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 Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim categoryID As Integer = _
        Convert.ToInt32(Request.QueryString("CategoryID"))
    ' Get information about the specified category
    Dim categoryAPI As New CategoriesBLL()
    Dim categories As Northwind.CategoriesDataTable = _
        categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID)
    Dim category As Northwind.CategoriesRow = 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)
End Sub

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 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer 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 bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.