Freigeben über


Speichern von zusätzlichen Benutzerinformationen (VB)

von Scott Mitchell

Hinweis

Seit diesem Artikel wurden die ASP.NET-Mitgliedschaftsanbieter von ASP.NET Identity abgelöst. Es wird dringend empfohlen, Apps so zu aktualisieren, dass sie die ASP.NET Identity-Plattform anstelle der Mitgliedschaftsanbieter verwenden, die zum Zeitpunkt des Schreibens dieses Artikels vorgestellt wurden. ASP.NET Identity bietet eine Reihe von Vorteilen gegenüber dem ASP.NET Mitgliedschaftssystem, darunter:

  • Bessere Leistung
  • Verbesserte Erweiterbarkeit und Testbarkeit
  • Unterstützung für OAuth, OpenID Connect und zweistufige Authentifizierung
  • Unterstützung der anspruchsbasierten Identität
  • Bessere Interoperabilität mit ASP.Net Core

Code herunterladen oder PDF herunterladen

In diesem Tutorial werden wir diese Frage beantworten, indem wir eine sehr rudimentäre Gastbuchanwendung erstellen. Dabei untersuchen wir verschiedene Optionen zum Modellieren von Benutzerinformationen in einer Datenbank und sehen dann, wie diese Daten den vom Mitgliedschaftsframework erstellten Benutzerkonten zugeordnet werden können.

Einführung

ASP. Das Mitgliedschaftsframework von NET bietet eine flexible Schnittstelle zum Verwalten von Benutzern. Die Mitgliedschafts-API umfasst Unter anderem Methoden zum Überprüfen von Anmeldeinformationen, zum Abrufen von Informationen über den aktuell angemeldeten Benutzer, zum Erstellen eines neuen Benutzerkontos und zum Löschen eines Benutzerkontos. Jedes Benutzerkonto im Mitgliedschaftsframework enthält nur die Eigenschaften, die zum Überprüfen von Anmeldeinformationen und zum Ausführen wesentlicher Benutzerkontobezogener Aufgaben erforderlich sind. Dies wird durch die Methoden und Eigenschaften der -Klasse belegt, die MembershipUserein Benutzerkonto im Membership-Framework modelliert. Diese Klasse verfügt über Eigenschaften wie UserName, Emailund IsLockedOut, und methoden wie GetPassword und .UnlockUser

Häufig müssen Anwendungen zusätzliche Benutzerinformationen speichern, die nicht im Mitgliedschaftsframework enthalten sind. Beispielsweise muss ein Onlinehändler jedem Benutzer die Möglichkeit geben, seine Liefer- und Abrechnungsadressen, Zahlungsinformationen, Liefereinstellungen und Telefonnummer zu speichern. Darüber hinaus ist jede Bestellung im System einem bestimmten Benutzerkonto zugeordnet.

Die MembershipUser -Klasse enthält keine Eigenschaften wie PhoneNumber oder DeliveryPreferencesPastOrdersoder . Wie können wir also die von der Anwendung benötigten Benutzerinformationen nachverfolgen und in das Mitgliedschaftsframework integrieren? In diesem Tutorial werden wir diese Frage beantworten, indem wir eine sehr rudimentäre Gastbuchanwendung erstellen. Dabei untersuchen wir verschiedene Optionen zum Modellieren von Benutzerinformationen in einer Datenbank und sehen dann, wie diese Daten den vom Mitgliedschaftsframework erstellten Benutzerkonten zugeordnet werden können. Jetzt geht‘s los!

Schritt 1: Erstellen des Datenmodells der Gastbuchanwendung

Es gibt eine Vielzahl von Techniken, die verwendet werden können, um Benutzerinformationen in einer Datenbank zu erfassen und sie den vom Mitgliedschaftsframework erstellten Benutzerkonten zuzuordnen. Um diese Techniken zu veranschaulichen, müssen wir die Tutorial-Webanwendung so erweitern, dass sie eine Art von benutzerbezogenen Daten erfasst. (Derzeit enthält das Datenmodell der Anwendung nur die Anwendungsdiensttabellen, die SqlMembershipProvidervon benötigt werden.)

Erstellen Sie eine sehr einfache Gastbuchanwendung, bei der ein authentifizierter Benutzer einen Kommentar hinterlassen kann. Zusätzlich zum Speichern von Gästebuchkommentaren können wir jedem Benutzer erlauben, seinen Heimatort, seine Homepage und seine Signatur zu speichern. Sofern angegeben, werden heimatort, Homepage und Signatur des Benutzers in jeder Nachricht angezeigt, die er im Gästebuch hinterlassen hat.

Hinzufügen derGuestbookCommentsTabelle

Um die Gästebuchkommentare zu erfassen, müssen Wir eine Datenbanktabelle mit dem Namen GuestbookComments erstellen, die Spalten wie CommentId, Subject, Bodyund CommentDateenthält. Außerdem muss jeder Datensatz in der Tabelle auf den GuestbookComments Benutzer verweisen, der den Kommentar verlassen hat.

Um diese Tabelle zu unserer Datenbank hinzuzufügen, navigieren Sie in Visual Studio zum Explorer Datenbank, und führen Sie einen Drilldown in die Datenbank durchSecurityTutorials. Klicken Sie mit der rechten Maustaste auf den Ordner Tabellen, und wählen Sie Neue Tabelle hinzufügen aus. Dadurch wird eine Schnittstelle angezeigt, die es uns ermöglicht, die Spalten für die neue Tabelle zu definieren.

Hinzufügen einer neuen Tabelle zur SecurityTutorials-Datenbank

Abbildung 1: Hinzufügen einer neuen Tabelle zur SecurityTutorials Datenbank (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Definieren Sie als Nächstes die GuestbookCommentsSpalten des Typs. Beginnen Sie mit dem Hinzufügen einer Spalte des CommentId Typs uniqueidentifier. In dieser Spalte wird jeder Kommentar im Gästebuch eindeutig identifiziert. Daher lassen Sie s nicht zu NULL , und markieren Sie ihn als Primärschlüssel der Tabelle. Anstatt einen Wert für das CommentId Feld für jedes INSERTFeld bereitzustellen, können wir angeben, dass für dieses Feld automatisch ein neuer uniqueidentifier Wert generiert werden soll, INSERT indem wir den Standardwert der Spalte auf NEWID()festlegen. Nachdem Sie dieses erste Feld hinzugefügt, es als Primärschlüssel markiert und den Standardwert festgelegt haben, sollte Ihr Bildschirm dem Screenshot in Abbildung 2 ähneln.

Hinzufügen einer primären Spalte mit dem Namen CommentId

Abbildung 2: Hinzufügen einer primären Spalte namens CommentId (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Fügen Sie als Nächstes eine Spalte mit dem Namen Subject vom Typ nvarchar(50) und eine Spalte mit dem Namen Body vom Typ nvarchar(MAX)hinzu, und heben Sie die Zuordnung NULL von s in beiden Spalten auf. Fügen Sie anschließend eine Spalte mit dem Namen vom CommentDate Typ datetimehinzu. Lassen Sie s nicht zu NULL , und legen Sie den Standardwert der CommentDate Spalte auf fest getdate().

Es bleibt nur noch, eine Spalte hinzuzufügen, die jedem Gastbuchkommentar ein Benutzerkonto ordnet. Eine Option wäre das Hinzufügen einer Spalte mit dem Namen UserName vom Typ nvarchar(256). Dies ist eine geeignete Wahl, wenn Sie einen anderen Mitgliedschaftsanbieter als den SqlMembershipProviderverwenden. Wenn Sie jedoch verwenden SqlMembershipProvider, wie wir in dieser Tutorialreihe sind, ist die UserName Spalte in der aspnet_Users Tabelle nicht garantiert eindeutig. Der aspnet_Users Primärschlüssel der Tabelle ist UserId und ist vom Typ uniqueidentifier. Daher benötigt die GuestbookComments Tabelle eine Spalte mit dem Namen UserId des Typs uniqueidentifier (Nichtzuordnungswerte NULL ). Fügen Sie diese Spalte hinzu.

Hinweis

Wie im Tutorial Erstellen des Mitgliedschaftsschemas in SQL Server erläutert, ist das Mitgliedschaftsframework so konzipiert, dass mehrere Webanwendungen mit unterschiedlichen Benutzerkonten denselben Benutzerspeicher gemeinsam nutzen können. Dazu werden Benutzerkonten in verschiedene Anwendungen partitioniert. Und obwohl jeder Benutzername innerhalb einer Anwendung garantiert eindeutig ist, kann derselbe Benutzername in verschiedenen Anwendungen verwendet werden, die denselben Benutzerspeicher verwenden. Es gibt eine zusammengesetzte UNIQUE Einschränkung in der aspnet_Users Tabelle für die UserName Felder und ApplicationId , aber nicht nur für das UserName Feld. Folglich ist es möglich, dass die aspnet_Users Tabelle zwei (oder mehr) Datensätze mit demselben UserName Wert aufweist. Es gibt jedoch eine UNIQUE Einschränkung für das Feld der aspnet_Users Tabelle UserId (da es sich um den Primärschlüssel handelt). Eine UNIQUE Einschränkung ist wichtig, da ohne sie keine Fremdschlüsseleinschränkung zwischen den GuestbookComments Tabellen und aspnet_Users festgelegt werden kann.

Nachdem Sie die UserId Spalte hinzugefügt haben, speichern Sie die Tabelle, indem Sie in der Symbolleiste auf das Symbol Speichern klicken. Nennen Sie die neue Tabelle GuestbookComments.

Wir haben ein letztes Problem mit der GuestbookComments Tabelle: Wir müssen eine Fremdschlüsseleinschränkung zwischen der GuestbookComments.UserId Spalte und der aspnet_Users.UserId Spalte erstellen. Klicken Sie dazu auf das Beziehungssymbol in der Symbolleiste, um das Dialogfeld Fremdschlüsselbeziehungen zu starten. (Alternativ können Sie dieses Dialogfeld starten, indem Sie zum Menü Tabelle Designer wechseln und Beziehungen auswählen.)

Klicken Sie in der unteren linken Ecke des Dialogfelds Fremdschlüsselbeziehungen auf die Schaltfläche Hinzufügen. Dadurch wird eine neue Fremdschlüsseleinschränkung hinzugefügt, obwohl wir weiterhin die Tabellen definieren müssen, die an der Beziehung beteiligt sind.

Verwenden des Dialogfelds Fremdschlüsselbeziehungen zum Verwalten der Fremdschlüsseleinschränkungen einer Tabelle

Abbildung 3: Verwenden des Dialogfelds Fremdschlüsselbeziehungen zum Verwalten der Fremdschlüsseleinschränkungen einer Tabelle (Klicken, um das vollständige Bild anzuzeigen)

Klicken Sie als Nächstes auf das Symbol mit den Auslassungspunkten in der Zeile "Tabellen- und Spaltenspezifikationen" auf der rechten Seite. Dadurch wird das Dialogfeld Tabellen und Spalten gestartet, in dem wir die Primärschlüsseltabelle und -spalte sowie die Fremdschlüsselspalte aus der GuestbookComments Tabelle angeben können. Wählen Sie aspnet_Users insbesondere und UserId als Primärschlüsseltabelle und -spalte und UserId aus der GuestbookComments Tabelle als Fremdschlüsselspalte aus (siehe Abbildung 4). Klicken Sie nach dem Definieren der Primär- und Fremdschlüsseltabellen und -spalten auf OK, um zum Dialogfeld Fremdschlüsselbeziehungen zurückzukehren.

Einrichten einer Fremdschlüsseleinschränkung zwischen den aspnet_Users und GuesbookKommentierungstabellen

Abbildung 4: Einrichten einer Fremdschlüsseleinschränkung zwischen tabellen aspnet_Users und GuesbookComments (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

An diesem Punkt wurde die Fremdschlüsseleinschränkung eingerichtet. Das Vorhandensein dieser Einschränkung gewährleistet die relationale Integrität zwischen den beiden Tabellen, indem sichergestellt wird, dass es nie einen Gastbucheintrag gibt, der sich auf ein nicht vorhandenes Benutzerkonto bezieht. Standardmäßig lässt eine Fremdschlüsseleinschränkung das Löschen eines übergeordneten Datensatzes nicht zu, wenn entsprechende untergeordnete Datensätze vorhanden sind. Das heißt, wenn ein Benutzer einen oder mehrere Gästebuchkommentare abgibt und wir dann versuchen, dieses Benutzerkonto zu löschen, schlägt die Löschung fehl, es sei denn, seine Gästebuchkommentare werden zuerst gelöscht.

Fremdschlüsseleinschränkungen können so konfiguriert werden, dass die zugeordneten untergeordneten Datensätze automatisch gelöscht werden, wenn ein übergeordneter Datensatz gelöscht wird. Mit anderen Worten, wir können diese Fremdschlüsseleinschränkung so einrichten, dass die Gastbucheinträge eines Benutzers automatisch gelöscht werden, wenn sein Benutzerkonto gelöscht wird. Erweitern Sie dazu den Abschnitt "INSERT and UPDATE Specification", und legen Sie die Eigenschaft "Regel löschen" auf Cascade fest.

Konfigurieren der Fremdschlüsseleinschränkung für kaskadierende Löschvorgänge

Abbildung 5: Konfigurieren der Fremdschlüsseleinschränkung für kaskadierende Löschvorgänge (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Um die Fremdschlüsseleinschränkung zu speichern, klicken Sie auf die Schaltfläche Schließen, um die Fremdschlüsselbeziehungen zu beenden. Klicken Sie dann auf das Symbol Speichern in der Symbolleiste, um die Tabelle und diese Beziehung zu speichern.

Speichern des Heimatortes, der Homepage und der Signatur des Benutzers

Die GuestbookComments Tabelle veranschaulicht, wie Informationen gespeichert werden, die eine 1:n-Beziehung mit Benutzerkonten gemeinsam haben. Da jedes Benutzerkonto über eine beliebige Anzahl von zugehörigen Kommentaren verfügt, wird diese Beziehung modelliert, indem eine Tabelle erstellt wird, die den Satz von Kommentaren enthält, die eine Spalte enthält, die jeden Kommentar zu einem bestimmten Benutzer zurückgibt. Bei Verwendung von SqlMembershipProviderwird dieser Link am besten hergestellt, indem eine Spalte mit dem Namen UserId des Typs uniqueidentifier und eine Fremdschlüsseleinschränkung zwischen dieser Spalte und erstellt wird aspnet_Users.UserId.

Wir müssen nun jedem Benutzerkonto drei Spalten zuordnen, um die Heimat des Benutzers, die Homepage und die Signatur des Benutzers zu speichern, die in seinen Gästebuchkommentaren angezeigt werden. Es gibt verschiedene Möglichkeiten, dies zu erreichen:

  • Fügen Sie dem neue Spalten hinzu.aspnet_UsersOderaspnet_MembershipTabellen. Ich würde diesen Ansatz nicht empfehlen, da er das schema ändert, das SqlMembershipProvidervon verwendet wird. Diese Entscheidung kann zurückkommen, um Sie auf dem Weg zu verfolgen. Was ist beispielsweise, wenn eine zukünftige Version von ASP.NET ein anderes SqlMembershipProvider Schema verwendet? Microsoft kann ein Tool zum Migrieren der ASP.NET 2.0-Daten SqlMembershipProvider in das neue Schema einschließen, aber wenn Sie das ASP.NET 2.0-Schema SqlMembershipProvider geändert haben, ist eine solche Konvertierung möglicherweise nicht möglich.

  • Verwenden Sie ASP. Profilframework von NET, das eine Profileigenschaft für den Heimatort, die Homepage und die Signatur definiert. ASP.NET enthält ein Profilframework, das zum Speichern zusätzlicher benutzerspezifischer Daten entwickelt wurde. Wie das Mitgliedschaftsframework wird das Profilframework auf dem Anbietermodell erstellt. Die .NET Framework wird mit einer SqlProfileProvider ausgeliefert, die Profildaten in einer SQL Server-Datenbank speichert. Tatsächlich verfügt unsere Datenbank bereits über die von SqlProfileProvider (aspnet_Profile) verwendete Tabelle, da sie beim Hinzufügen der Anwendungsdienste im Tutorial Erstellen des Mitgliedschaftsschemas in SQL Server hinzugefügt wurde.
    Der Standard Vorteil des Profilframeworks besteht darin, dass Entwickler die Profileigenschaften in Web.config definieren können. Es muss kein Code geschrieben werden, um die Profildaten in den und aus dem zugrunde liegenden Datenspeicher zu serialisieren. Kurz gesagt, es ist unglaublich einfach, eine Reihe von Profileigenschaften zu definieren und mit ihnen im Code zu arbeiten. Das Profilsystem lässt jedoch bei der Versionsverwaltung viel zu wünschen übrig. Wenn Sie also über eine Anwendung verfügen, bei der Sie erwarten, dass zu einem späteren Zeitpunkt neue benutzerspezifische Eigenschaften hinzugefügt oder vorhandene eigenschaften entfernt oder geändert werden, ist das Profilframework möglicherweise nicht die beste Option. Darüber hinaus speichert der SqlProfileProvider die Profileigenschaften in einer stark denormalisierten Weise, sodass es so gut wie unmöglich ist, Abfragen direkt für die Profildaten auszuführen (z. B. wie viele Benutzer eine Heimatstadt new York haben).
    Weitere Informationen zum Profilframework finden Sie im Abschnitt "Weitere Lesungen" am Ende dieses Tutorials.

  • Fügen Sie diese drei Spalten einer neuen Tabelle in der Datenbank hinzu, und stellen Sie eine 1:1-Beziehung zwischen dieser Tabelle undaspnet_Users. Dieser Ansatz erfordert etwas mehr Arbeit als mit dem Profilframework, bietet jedoch maximale Flexibilität bei der Modellierung der zusätzlichen Benutzereigenschaften in der Datenbank. Dies ist die Option, die wir in diesem Tutorial verwenden werden.

Wir erstellen eine neue Tabelle mit dem Namen UserProfiles , um die Heimatstadt, die Homepage und die Signatur für jeden Benutzer zu speichern. Klicken Sie im Fenster Datenbank Explorer mit der rechten Maustaste auf den Ordner Tabellen, und wählen Sie aus, um eine neue Tabelle zu erstellen. Benennen Sie die erste Spalte, UserId und legen Sie ihren Typ auf fest uniqueidentifier. Werte nicht zulassen NULL , und markieren Sie die Spalte als Primärschlüssel. Fügen Sie als Nächstes Spalten mit dem Namen : HomeTown vom Typ nvarchar(50); HomepageUrl vom Typ nvarchar(100); und Signatur des Typs nvarchar(500)hinzu. Jede dieser drei Spalten kann einen NULL Wert akzeptieren.

Erstellen der UserProfiles-Tabelle

Abbildung 6: Erstellen der UserProfiles Tabelle (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Speichern Sie die Tabelle, und nennen Sie sie UserProfiles. Richten Sie schließlich eine Fremdschlüsseleinschränkung zwischen dem Feld der UserProfiles Tabelle UserId und dem aspnet_Users.UserId Feld ein. Wie bei der Fremdschlüsseleinschränkung zwischen den GuestbookComments Tabellen und aspnet_Users lassen Sie diese Einschränkung kaskadierende Löschvorgänge ausführen. Da das UserId Feld in UserProfiles der Primärschlüssel ist, wird dadurch sichergestellt, dass nicht mehr als ein Datensatz in der UserProfiles Tabelle für jedes Benutzerkonto vorhanden ist. Dieser Beziehungstyp wird als 1:1 bezeichnet.

Nachdem wir das Datenmodell erstellt haben, können wir es nun verwenden. In den Schritten 2 und 3 sehen wir uns an, wie der aktuell angemeldete Benutzer seine Heimat, Homepage und Signaturinformationen anzeigen und bearbeiten kann. In Schritt 4 erstellen wir die Schnittstelle für authentifizierte Benutzer, um neue Kommentare an das Gästebuch zu übermitteln und die vorhandenen anzuzeigen.

Schritt 2: Anzeigen von Heimatort, Homepage und Signatur des Benutzers

Es gibt eine Vielzahl von Möglichkeiten, um es dem aktuell angemeldeten Benutzer zu ermöglichen, seine Heimat, Homepage und Signaturinformationen anzuzeigen und zu bearbeiten. Wir könnten die Benutzeroberfläche manuell mit TextBox- und Label-Steuerelementen erstellen oder eines der Datenwebsteuerelemente verwenden, z. B. das DetailsView-Steuerelement. Um die Datenbank SELECT und UPDATE anweisungen auszuführen, können wir ADO.NET Code in der CodeBehind-Klasse unserer Seite schreiben oder alternativ einen deklarativen Ansatz mit SqlDataSource verwenden. Im Idealfall würde unsere Anwendung eine mehrstufige Architektur enthalten, die wir entweder programmgesteuert aus der CodeBehind-Klasse der Seite oder deklarativ über das ObjectDataSource-Steuerelement aufrufen könnten.

Da sich diese Tutorialreihe auf Formularauthentifizierung, Autorisierung, Benutzerkonten und Rollen konzentriert, wird es keine ausführliche Erläuterung dieser verschiedenen Datenzugriffsoptionen geben oder warum eine mehrstufige Architektur gegenüber der Ausführung von SQL-Anweisungen direkt von der seite ASP.NET bevorzugt wird. Ich werde die Verwendung von DetailsView und SqlDataSource – die schnellste und einfachste Option – durchlaufen, aber die besprochenen Konzepte können sicherlich auf alternative Websteuerelemente und Datenzugriffslogik angewendet werden. Weitere Informationen zum Arbeiten mit Daten in ASP.NET finden Sie in der Tutorialreihe Arbeiten mit Daten in ASP.NET 2.0 .

Öffnen Sie die AdditionalUserInfo.aspx Seite im Membership Ordner, und fügen Sie der Seite ein DetailsView-Steuerelement hinzu. Legen Sie dessen ID-Eigenschaft auf UserProfile fest, und löschen Sie die Width Eigenschaften und Height . Erweitern Sie das Smarttag von DetailsView, und legen Sie fest, dass es an ein neues Datenquellensteuerelement gebunden werden soll. Dadurch wird der DataSource-Konfigurations-Assistent gestartet (siehe Abbildung 7). Im ersten Schritt werden Sie aufgefordert, den Datenquellentyp anzugeben. Da wir eine direkte Verbindung mit der SecurityTutorials Datenbank herstellen möchten, wählen Sie das Symbol Datenbank aus, und geben Sie als UserProfileDataSourceanID.

Hinzufügen eines neuen SqlDataSource-Steuerelements namens UserProfileDataSource

Abbildung 7: Hinzufügen eines neuen SqlDataSource-Steuerelements namens UserProfileDataSource (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Auf dem nächsten Bildschirm wird zur Verwendung der Datenbank aufgefordert. Wir haben bereits eine Verbindungszeichenfolge Web.config für die SecurityTutorials Datenbank definiert. Dieser Verbindungszeichenfolge Name sollte SecurityTutorialsConnectionString sich in der Dropdownliste befinden. Wählen Sie diese Option aus, und klicken Sie auf Weiter.

Wählen Sie securityTutorialsConnectionString aus der Drop-Down-Liste aus.

Abbildung 8: Auswählen SecurityTutorialsConnectionString aus der Drop-Down-Liste (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Auf dem folgenden Bildschirm werden wir aufgefordert, die abzufragende Tabelle und die abzufragenden Spalten anzugeben. Wählen Sie die UserProfiles Tabelle aus der Dropdownliste aus, und überprüfen Sie alle Spalten.

Zurückführen aller Spalten aus der Tabelle

Abbildung 9: Zurückführen aller Spalten aus der UserProfiles Tabelle (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Die aktuelle Abfrage in Abbildung 9 gibt alle Datensätze in UserProfileszurück, aber wir interessieren uns nur für den aktuell angemeldeten Benutzerdatensatz. Klicken Sie zum Hinzufügen einer WHERE Klausel auf die WHERE Schaltfläche, um das Dialogfeld Klausel hinzufügen WHERE zu öffnen (siehe Abbildung 10). Hier können Sie die Spalte, nach der gefiltert werden soll, den Operator und die Quelle des Filterparameters auswählen. Wählen Sie UserId als Spalte und "=" als Operator aus.

Leider gibt es keine integrierte Parameterquelle, um den Wert des UserId aktuell angemeldeten Benutzers zurückzugeben. Wir müssen diesen Wert programmgesteuert abrufen. Legen Sie daher die Dropdownliste Quelle auf "Keine" fest, klicken Sie auf die Schaltfläche Hinzufügen, um den Parameter hinzuzufügen, und klicken Sie dann auf OK.

Hinzufügen eines Filterparameters für die UserId-Spalte

Abbildung 10: Hinzufügen eines Filterparameters für die UserId Spalte (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nachdem Sie auf OK geklickt haben, werden Sie zu dem in Abbildung 9 gezeigten Bildschirm zurückkehren. Dieses Mal sollte die SQL-Abfrage am unteren Bildschirmrand jedoch eine WHERE -Klausel enthalten. Klicken Sie auf Weiter, um zum Bildschirm "Testabfrage" zu wechseln. Hier können Sie die Abfrage ausführen und die Ergebnisse anzeigen. Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.

Nach Abschluss des DataSource-Konfigurations-Assistenten erstellt Visual Studio das SqlDataSource-Steuerelement basierend auf den im Assistenten angegebenen Einstellungen. Darüber hinaus wird BoundFields manuell der DetailsView für jede Spalte hinzugefügt, die von sqlDataSource SelectCommandzurückgegeben wird. Es ist nicht erforderlich, das UserId Feld in der DetailsView anzuzeigen, da der Benutzer diesen Wert nicht kennen muss. Sie können dieses Feld direkt aus dem deklarativen Markup des DetailsView-Steuerelements entfernen oder indem Sie im Smarttag auf den Link "Felder bearbeiten" klicken.

An diesem Punkt sollte das deklarative Markup Ihrer Seite in etwa wie folgt aussehen:

<asp:DetailsView ID="UserProfile" runat="server"
          AutoGenerateRows="False" DataKeyNames="UserId"

          DataSourceID="UserProfileDataSource">
     <Fields>
          <asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
               SortExpression="HomeTown" />
          <asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"

               SortExpression="HomepageUrl" />
          <asp:BoundField DataField="Signature" HeaderText="Signature"
               SortExpression="Signature" />
     </Fields>

</asp:DetailsView>
<asp:SqlDataSource ID="UserProfileDataSource" runat="server"
          ConnectionString="<%$ ConnectionStrings:SecurityTutorialsConnectionString %>"
          SelectCommand="SELECT [UserId], [HomeTown], [HomepageUrl], [Signature] FROM
          [UserProfiles] WHERE ([UserId] = @UserId)">
     <SelectParameters>

          <asp:Parameter Name="UserId" Type="Object" />
     </SelectParameters>
</asp:SqlDataSource>

Wir müssen den Parameter des SqlDataSource-Steuerelements UserId programmgesteuert auf den des aktuell angemeldeten Benutzers festlegen, UserId bevor die Daten ausgewählt werden. Dies kann erreicht werden, indem Sie einen Ereignishandler für das SqlDataSource-Ereignis Selecting erstellen und dort den folgenden Code hinzufügen:

Protected Sub UserProfileDataSource_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs) Handles UserProfileDataSource.Selecting
     ' Get a reference to the currently logged on user
     Dim currentUser As MembershipUser = Membership.GetUser()

     ' Determine the currently logged on user's UserId value
     Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)

     ' Assign the currently logged on user's UserId to the @UserId parameter
     e.Command.Parameters("@UserId").Value = currentUserId
End Sub

Der obige Code beginnt mit dem Abrufen eines Verweises auf den aktuell angemeldeten Benutzer, indem die -Methode der Membership -Klasse GetUser aufgerufen wird. Dadurch wird ein MembershipUser -Objekt zurückgegeben, dessen ProviderUserKey -Eigenschaft den UserIdenthält. Der UserId Wert wird dann dem Parameter von @UserId SqlDataSource zugewiesen.

Hinweis

Die Membership.GetUser() -Methode gibt Informationen zum aktuell angemeldeten Benutzer zurück. Wenn ein anonymer Benutzer die Seite besucht, wird der Wert zurückgegeben Nothing. In einem solchen Fall führt dies zu einer NullReferenceException in der folgenden Codezeile, wenn Sie versuchen, die ProviderUserKey Eigenschaft zu lesen. Natürlich müssen wir uns keine Gedanken über Membership.GetUser() die Rückgabe von Nothing auf der AdditionalUserInfo.aspx Seite machen, da wir die URL-Autorisierung in einem vorherigen Tutorial so konfiguriert haben, dass nur authentifizierte Benutzer auf die ASP.NET Ressourcen in diesem Ordner zugreifen konnten. Wenn Sie auf Informationen über den aktuell angemeldeten Benutzer auf einer Seite zugreifen müssen, auf der anonymer Zugriff zulässig ist, vergewissern Sie sich, dass das MembershipUser von der GetUser() Methode zurückgegebene Objekt nicht Nothing ist, bevor Sie auf die Eigenschaften verweisen.

Wenn Sie die AdditionalUserInfo.aspx Seite über einen Browser besuchen, wird eine leere Seite angezeigt, da wir der UserProfiles Tabelle noch keine Zeilen hinzufügen müssen. In Schritt 6 erfahren Sie, wie Sie das CreateUserWizard-Steuerelement so anpassen, dass der UserProfiles Tabelle automatisch eine neue Zeile hinzugefügt wird, wenn ein neues Benutzerkonto erstellt wird. Vorerst müssen wir jedoch manuell einen Datensatz in der Tabelle erstellen.

Navigieren Sie in Visual Studio zum Explorer Datenbank, und erweitern Sie den Ordner Tabellen. Klicken Sie mit der rechten Maustaste auf die aspnet_Users Tabelle, und wählen Sie "Tabellendaten anzeigen", um die Datensätze in der Tabelle anzuzeigen. Führen Sie dasselbe für die UserProfiles Tabelle aus. Abbildung 11 zeigt diese Ergebnisse, wenn sie vertikal angeordnet werden. In meiner Datenbank gibt es derzeit aspnet_Users Datensätze für Bruce, Fred und Tito, aber keine Datensätze in der UserProfiles Tabelle.

Der Inhalt der Tabellen aspnet_Users und UserProfiles wird angezeigt.

Abbildung 11: Der Inhalt der aspnet_Users Tabellen und UserProfiles wird angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Fügen Sie der UserProfiles Tabelle einen neuen Datensatz hinzu, indem Sie manuell Werte für die HomeTownFelder , HomepageUrlund Signature eingeben. Die einfachste Möglichkeit, einen gültigen UserId Wert im neuen UserProfiles Datensatz abzurufen, besteht darin, das UserId Feld aus einem bestimmten Benutzerkonto in der aspnet_Users Tabelle auszuwählen und es zu kopieren und in das UserId Feld in UserProfileseinzufügen. Abbildung 12 zeigt die UserProfiles Tabelle, nachdem ein neuer Datensatz für Bruce hinzugefügt wurde.

Ein Datensatz wurde zu UserProfiles für Bruce hinzugefügt.

Abbildung 12: Ein Datensatz wurde für Bruce hinzugefügt UserProfiles (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Kehren Sie zu zurück, die AdditionalUserInfo.aspx pageals Bruce angemeldet ist. Wie Abbildung 13 zeigt, werden Bruces Einstellungen angezeigt.

Dem aktuell besuchten Benutzer werden seine Einstellungen angezeigt.

Abbildung 13: Dem derzeit besuchenden Benutzer werden seine Einstellungen angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Fügen Sie in der UserProfiles Tabelle für jeden Mitgliedschaftsbenutzer manuell Datensätze hinzu. In Schritt 6 erfahren Sie, wie Sie das CreateUserWizard-Steuerelement so anpassen, dass der UserProfiles Tabelle automatisch eine neue Zeile hinzugefügt wird, wenn ein neues Benutzerkonto erstellt wird.

Schritt 3: Zulassen, dass der Benutzer seine Heimatstadt, Homepage und Signatur bearbeiten kann

Zu diesem Zeitpunkt kann der aktuell angemeldete Benutzer seine Heimat, Homepage und Signatureinstellung einsehen, aber noch nicht ändern. Aktualisieren Wir nun das DetailsView-Steuerelement, damit die Daten bearbeitet werden können.

Zunächst müssen wir eine UpdateCommand für sqlDataSource hinzufügen und dabei die auszuführende Anweisung und die UPDATE entsprechenden Parameter angeben. Wählen Sie sqlDataSource aus, und klicken Sie im Eigenschaftenfenster auf die Auslassungspunkte neben der UpdateQuery-Eigenschaft, um das Dialogfeld Command and Parameter Editor anzuzeigen. Geben Sie die folgende UPDATE Anweisung in das Textfeld ein:

UPDATE UserProfiles SET
     HomeTown = @HomeTown,
     HomepageUrl = @HomepageUrl,
     Signature = @Signature
WHERE UserId = @UserId

Klicken Sie als Nächstes auf die Schaltfläche "Parameter aktualisieren", um einen Parameter in der Auflistung des SqlDataSource-Steuerelements UpdateParameters für jeden parameter in der UPDATE -Anweisung zu erstellen. Lassen Sie die Quelle für alle Parameter auf Keine festgelegt, und klicken Sie auf die Schaltfläche OK, um das Dialogfeld abzuschließen.

Geben Sie updateCommand und UpdateParameters von SqlDataSource an.

Abbildung 14: Angeben der SqlDataSource und UpdateCommandUpdateParameters (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Aufgrund der Ergänzungen, die wir am SqlDataSource-Steuerelement vorgenommen haben, kann das DetailsView-Steuerelement jetzt die Bearbeitung unterstützen. Aktivieren Sie im Smarttag von DetailsView das Kontrollkästchen "Bearbeitung aktivieren". Dadurch wird der Auflistung des Steuerelements Fields ein CommandField hinzugefügt, dessen ShowEditButton -Eigenschaft auf True festgelegt ist. Dadurch wird eine Schaltfläche Bearbeiten gerendert, wenn detailsView im schreibgeschützten Modus und die Schaltflächen Aktualisieren und Abbrechen angezeigt wird, wenn sie im Bearbeitungsmodus angezeigt wird. Anstatt jedoch zu verlangen, dass der Benutzer auf Bearbeiten klicken muss, können wir detailsView in einem "immer bearbeitbaren" Zustand rendern lassen, indem wir die -Eigenschaft desDefaultMode DetailsView-Steuerelements auf Editfestlegen.

Mit diesen Änderungen sollte das deklarative Markup Ihres DetailsView-Steuerelements in etwa wie folgt aussehen:

<asp:DetailsView ID="UserProfile" runat="server"

          AutoGenerateRows="False" DataKeyNames="UserId"
          DataSourceID="UserProfileDataSource" DefaultMode="Edit">
     <Fields>
          <asp:BoundField DataField="HomeTown" HeaderText="HomeTown"

               SortExpression="HomeTown" />
          <asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
               SortExpression="HomepageUrl" />
          <asp:BoundField DataField="Signature" HeaderText="Signature"

               SortExpression="Signature" />
          <asp:CommandField ShowEditButton="True" />
     </Fields>
</asp:DetailsView>

Beachten Sie das Hinzufügen von CommandField und der DefaultMode -Eigenschaft.

Testen Sie diese Seite über einen Browser. Beim Besuch mit einem Benutzer, der über einen entsprechenden Datensatz in UserProfilesverfügt, werden die Einstellungen des Benutzers in einer bearbeitbaren Benutzeroberfläche angezeigt.

DetailsView rendert eine bearbeitbare Schnittstelle

Abbildung 15: DetailsView rendert eine bearbeitbare Schnittstelle (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Versuchen Sie, die Werte zu ändern, und klicken Sie auf die Schaltfläche Aktualisieren. Es scheint, als ob nichts geschieht. Es gibt ein Postback, und die Werte werden in der Datenbank gespeichert, aber es gibt kein visuelles Feedback, dass die Speicherung erfolgt ist.

Um dies zu beheben, kehren Sie zu Visual Studio zurück, und fügen Sie ein Label-Steuerelement über der DetailsView hinzu. Legen Sie auf SettingsUpdatedMessageID , die Text -Eigenschaft auf "Ihre Einstellungen wurden aktualisiert" und die Visible Eigenschaften und EnableViewState auf festFalse.

<asp:Label ID="SettingsUpdatedMessage" runat="server"
     Text="Your settings have been updated."
     EnableViewState="false"
     Visible="false">
</asp:Label>

Wir müssen die SettingsUpdatedMessage Bezeichnung anzeigen, wenn die DetailsView aktualisiert wird. Erstellen Sie hierzu einen Ereignishandler für das Ereignis von ItemUpdated DetailsView, und fügen Sie den folgenden Code hinzu:

Protected Sub UserProfile_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles UserProfile.ItemUpdated
     SettingsUpdatedMessage.Visible = True
End Sub

Kehren Sie über einen Browser zur AdditionalUserInfo.aspx Seite zurück, und aktualisieren Sie die Daten. Dieses Mal wird eine hilfreiche status Meldung angezeigt.

Eine kurze Meldung wird angezeigt, wenn die Einstellungen aktualisiert werden.

Abbildung 16: Eine kurze Meldung wird angezeigt, wenn die Einstellungen aktualisiert werden (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Die Bearbeitungsoberfläche des DetailsView-Steuerelements lässt viel zu wünschen übrig. Es werden Textfelder in Standardgröße verwendet, aber das Feld Signatur sollte wahrscheinlich ein mehrzeiliges Textfeld sein. Ein RegularExpressionValidator sollte verwendet werden, um sicherzustellen, dass die Homepage-URL bei Eingabe mit "http://" oder "https://" beginnt. Da die Eigenschaft des DetailsView-Steuerelements auf Editfestgelegt istDefaultMode, führt die Schaltfläche Abbrechen keine Aktionen aus. Sie sollte entweder entfernt oder beim Klicken auf eine andere Seite umgeleitet werden (z ~/Default.aspx. B. ). Ich belasse diese Verbesserungen als Übung für den Leser.

Derzeit stellt die Website keine Links zu der AdditionalUserInfo.aspx Seite bereit. Die einzige Möglichkeit, sie zu erreichen, besteht darin, die URL der Seite direkt in die Adressleiste des Browsers einzugeben. Fügen Sie auf der Site.master Seite master einen Link zu dieser Seite hinzu.

Denken Sie daran, dass die Seite master ein LoginView-Websteuerelement in ihrem LoginContent ContentPlaceHolder enthält, das unterschiedliche Markups für authentifizierte und anonyme Besucher anzeigt. Aktualisieren Sie die LoginView-Steuerelemente LoggedInTemplate , um einen Link zur AdditionalUserInfo.aspx Seite einzuschließen. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup des LoginView-Steuerelements in etwa wie folgt aussehen:

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          Welcome back,
          <asp:LoginName ID="LoginName1" runat="server" />.

          <br />
          <asp:HyperLink ID="lnkUpdateSettings" runat="server" 
               NavigateUrl="~/Membership/AdditionalUserInfo.aspx">
               Update Your Settings</asp:HyperLink>
     </LoggedInTemplate>
     <AnonymousTemplate>

          Hello, stranger.
     </AnonymousTemplate>
</asp:LoginView>

Beachten Sie das Hinzufügen des lnkUpdateSettings HyperLink-Steuerelements zu .LoggedInTemplate Wenn dieser Link vorhanden ist, können authentifizierte Benutzer schnell zur Seite springen, um ihre Heimat, Homepage und Signatureinstellungen anzuzeigen und zu ändern.

Schritt 4: Hinzufügen neuer Gästebuchkommentare

Auf Guestbook.aspx der Seite können authentifizierte Benutzer das Gästebuch anzeigen und einen Kommentar hinterlassen. Beginnen wir mit dem Erstellen der Benutzeroberfläche, um neue Gästebuchkommentare hinzuzufügen.

Öffnen Sie die Guestbook.aspx Seite in Visual Studio, und erstellen Sie eine Benutzeroberfläche, die aus zwei TextBox-Steuerelementen besteht: eines für den Betreff des neuen Kommentars und eines für den Textkörper. Legen Sie die Eigenschaft des ersten TextBox-Steuerelements ID auf Subject und seine Columns -Eigenschaft auf 40 fest. Legen Sie die zweite ID auf Bodyfest, WidthTextMode und MultiLinelegen Sie die Eigenschaften und Rows auf "95%" bzw. 8 fest. Fügen Sie zum Abschließen der Benutzeroberfläche ein Button-Websteuerelement mit dem Namen PostCommentButton hinzu, und legen Sie dessen Text Eigenschaft auf "Kommentar posten" fest.

Da jeder Gastbuchkommentar einen Betreff und einen Text erfordert, fügen Sie für jedes Der TextBoxes einen RequiredFieldValidator hinzu. Legen Sie die ValidationGroup -Eigenschaft dieser Steuerelemente auf "EnterComment" fest. Legen Sie ebenfalls die PostCommentButton -Eigenschaft des Steuerelements ValidationGroup auf "EnterComment" fest. Weitere Informationen zu ASP. Die Validierungssteuerelemente von NET finden Sie unter Formularüberprüfung in ASP.NET.

Nach dem Erstellen der Benutzeroberfläche sollte das deklarative Markup Ihrer Seite in etwa wie folgt aussehen:

<h3>Leave a Comment</h3>
<p>
     <b>Subject:</b>
     <asp:RequiredFieldValidator ID="SubjectReqValidator" runat="server"

          ErrorMessage="You must provide a value for Subject"
          ControlToValidate="Subject" ValidationGroup="EnterComment">
     </asp:RequiredFieldValidator><br />
     <asp:TextBox ID="Subject" Columns="40" runat="server"></asp:TextBox>

</p>
<p>
     <b>Body:</b>
     <asp:RequiredFieldValidator ID="BodyReqValidator" runat="server"
          ControlToValidate="Body"

          ErrorMessage="You must provide a value for Body" ValidationGroup="EnterComment">
     </asp:RequiredFieldValidator><br />
     <asp:TextBox ID="Body" TextMode="MultiLine" Width="95%"

          Rows="8" runat="server"></asp:TextBox>
</p>
<p>
     <asp:Button ID="PostCommentButton" runat="server" 

          Text="Post Your Comment"
          ValidationGroup="EnterComment" />
</p>

Wenn die Benutzeroberfläche abgeschlossen ist, besteht die nächste Aufgabe darin, einen neuen Datensatz in die GuestbookComments Tabelle einzufügen, wenn auf geklickt PostCommentButton wird. Dies kann auf verschiedene Arten erreicht werden: Wir können ADO.NET Code in den Ereignishandler der Schaltfläche Click schreiben. Wir können der Seite ein SqlDataSource-Steuerelement hinzufügen, dessen InsertCommandkonfigurieren und dann die - Insert Methode aus dem Click Ereignishandler aufrufen; oder wir könnten eine mittlere Ebene erstellen, die für das Einfügen neuer Gastbuchkommentare verantwortlich war, und diese Funktionalität über den Click Ereignishandler aufrufen. Da wir uns in Schritt 3 mit der Verwendung einer SqlDataSource befasst haben, verwenden wir hier ADO.NET Code.

Hinweis

Die ADO.NET Klassen, die für den programmgesteuerten Zugriff auf Daten aus einer Microsoft SQL Server-Datenbank verwendet werden, befinden sich im System.Data.SqlClient Namespace. Möglicherweise müssen Sie diesen Namespace in die CodeBehind-Klasse Ihrer Seite importieren (d. h. Imports System.Data.SqlClient).

Erstellen Sie einen Ereignishandler für das PostCommentButton-Ereignis, Click und fügen Sie den folgenden Code hinzu:

Protected Sub PostCommentButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PostCommentButton.Click
     If Not Page.IsValid Then Exit Sub

     ' Determine the currently logged on user's UserId
     Dim currentUser As MembershipUser = Membership.GetUser()
     Dim currentUserId As Guid = CType(currentUser.ProviderUserKey, Guid)

     ' Insert a new record into GuestbookComments
     Dim connectionString As String = 
          ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
     Dim insertSql As String = "INSERT INTO GuestbookComments(Subject, Body, UserId)
          VALUES(@Subject, @Body, @UserId)"

     Using myConnection As New SqlConnection(connectionString)

          myConnection.Open()
          Dim myCommand As New SqlCommand(insertSql, myConnection)
          myCommand.Parameters.AddWithValue("@Subject", Subject.Text.Trim())
          myCommand.Parameters.AddWithValue("@Body", Body.Text.Trim())
          myCommand.Parameters.AddWithValue("@UserId", currentUserId)
          myCommand.ExecuteNonQuery()
          myConnection.Close()
     End Using

     ' "Reset" the Subject and Body TextBoxes

     Subject.Text = String.Empty
     Body.Text = String.Empty
End Sub

Der Click Ereignishandler überprüft zunächst, ob die vom Benutzer bereitgestellten Daten gültig sind. Wenn dies nicht der Fall ist, wird der Ereignishandler vor dem Einfügen eines Datensatzes beendet. Wenn die angegebenen Daten gültig sind, wird der Wert des UserId aktuell angemeldeten Benutzers abgerufen und in der currentUserId lokalen Variablen gespeichert. Dieser Wert wird benötigt, da beim Einfügen eines UserId Datensatzes in GuestbookCommentseinen -Wert verwendet werden muss.

Anschließend wird der Verbindungszeichenfolge für die SecurityTutorials Datenbank aus Web.config abgerufen, und die INSERT SQL-Anweisung wird angegeben. Anschließend SqlConnection wird ein -Objekt erstellt und geöffnet. Als Nächstes wird ein SqlCommand -Objekt erstellt, und die Werte für die in der INSERT Abfrage verwendeten Parameter werden zugewiesen. Anschließend INSERT wird die Anweisung ausgeführt, und die Verbindung wird geschlossen. Am Ende des Ereignishandlers werden die Eigenschaften und Body die Subject TextBoxes-Eigenschaften Text gelöscht, sodass die Werte des Benutzers nicht über das Postback gespeichert werden.

Testen Sie diese Seite in einem Browser. Da sich diese Seite im Membership Ordner befindet, ist sie für anonyme Besucher nicht zugänglich. Daher müssen Sie sich zuerst anmelden (sofern noch nicht geschehen). Geben Sie einen Wert in die Subject Textfelder und Body ein, und klicken Sie auf die PostCommentButton Schaltfläche. Dies führt dazu, dass ein neuer Datensatz zu GuestbookCommentshinzugefügt wird. Beim Postback werden betreff und text, den Sie angegeben haben, aus den TextBoxen zurückgesetzt.

Nach dem Klicken auf die PostCommentButton Schaltfläche gibt es kein visuelles Feedback, dass der Kommentar dem Gästebuch hinzugefügt wurde. Wir müssen diese Seite noch aktualisieren, um die vorhandenen Gästebuchkommentare anzuzeigen, was wir in Schritt 5 tun werden. Sobald wir dies erreicht haben, wird der gerade hinzugefügte Kommentar in der Liste der Kommentare angezeigt und liefert ein angemessenes visuelles Feedback. Vergewissern Sie sich vorerst, dass Ihr Gastbuchkommentar gespeichert wurde, indem Sie den Inhalt der GuestbookComments Tabelle untersuchen.

Abbildung 17 zeigt den Inhalt der GuestbookComments Tabelle, nachdem zwei Kommentare verlassen wurden.

Sie können die Gästebuchkommentare in der Tabelle GästebuchKommentare anzeigen.

Abbildung 17: Sie können die Gästebuchkommentare in der GuestbookComments Tabelle sehen (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Wenn ein Benutzer versucht, einen Gastbuchkommentar einzufügen, der potenziell gefährliches Markup (z. B. HTML) enthält, löst ASP.NET einen aus HttpRequestValidationException. Weitere Informationen zu dieser Ausnahme, warum sie ausgelöst wird und wie Benutzer potenziell gefährliche Werte übermitteln können, finden Sie im Whitepaper Zur Anforderungsüberprüfung.

Schritt 5: Auflisten der vorhandenen Gästebuchkommentare

Zusätzlich zum Hinterlassen von Kommentaren sollte ein Benutzer, der die Guestbook.aspx Seite besucht, auch in der Lage sein, die vorhandenen Kommentare des Gästebuchs anzuzeigen. Fügen Sie dazu am unteren Rand der Seite ein ListView-Steuerelement mit dem Namen CommentList hinzu.

Hinweis

Das ListView-Steuerelement ist neu in ASP.NET Version 3.5. Es wurde entwickelt, um eine Liste von Elementen in einem sehr anpassbaren und flexiblen Layout anzuzeigen, bietet aber dennoch integrierte Bearbeitungs-, Einfüge-, Lösch-, Paging- und Sortierfunktionen wie gridView. Wenn Sie ASP.NET 2.0 verwenden, müssen Sie stattdessen das DataList- oder Repeater-Steuerelement verwenden. Weitere Informationen zur Verwendung der ListView finden Sie unter Scott Guthries Blogeintrag Das asp:ListView-Steuerelement und in meinem Artikel Anzeigen von Daten mit dem ListView-Steuerelement.

Öffnen Sie das Smarttag von ListView, und binden Sie das Steuerelement in der Dropdownliste Datenquelle auswählen an eine neue Datenquelle. Wie in Schritt 2 gezeigt, wird der Datenquellenkonfigurations-Assistent gestartet. Wählen Sie das Symbol Datenbank aus, benennen Sie die resultierende SqlDataSource CommentsDataSource, und klicken Sie auf OK. Wählen Sie als Nächstes die SecurityTutorialsConnectionString Verbindungszeichenfolge aus der Dropdownliste aus, und klicken Sie auf Weiter.

An diesem Punkt in Schritt 2 haben wir die abzufragenden Daten angegeben, indem wir die UserProfiles Tabelle aus der Dropdownliste auswählen und die zurückzugebenden Spalten auswählen (siehe Abbildung 9). Dieses Mal möchten wir jedoch eine SQL-Anweisung erstellen, die nicht nur die Datensätze aus GuestbookComments, sondern auch die Heimatstadt, die Homepage, die Signatur und den Benutzernamen des Kommentators zurückzieht. Wählen Sie daher das Optionsfeld "Benutzerdefinierte SQL-Anweisung oder gespeicherte Prozedur angeben" aus, und klicken Sie auf Weiter.

Dadurch wird der Bildschirm "Benutzerdefinierte Anweisungen oder gespeicherte Prozeduren definieren" geöffnet. Klicken Sie auf die Schaltfläche Abfrage-Generator, um die Abfrage grafisch zu erstellen. Der Abfrage-Generator fordert uns zunächst auf, die Tabellen anzugeben, die wir abfragen möchten. Wählen Sie die GuestbookCommentsTabellen , UserProfilesund aus, und aspnet_Users klicken Sie auf OK. Dadurch werden alle drei Tabellen der Entwurfsoberfläche hinzugefügt. Da es Fremdschlüsseleinschränkungen zwischen den GuestbookCommentsTabellen , UserProfilesund aspnet_Users gibt der Abfrage-Generator diese Tabellen automatisch JOIN aus.

Es bleibt nur noch, die zurückzugebenden Spalten anzugeben. Wählen Sie in der Tabelle die Spalten , Bodyund CommentDate aus. Geben Sie die HomeTownSpalten , HomepageUrlund Signature aus der UserProfiles Tabelle zurück, und geben Sie von zurück UserNameaspnet_Users.SubjectGuestbookComments Fügen Sie außerdem "ORDER BY CommentDate DESC" am Ende der SELECT Abfrage hinzu, sodass die neuesten Beiträge zuerst zurückgegeben werden. Nachdem Sie diese Auswahl getroffen haben, sollte Ihre Abfrage-Generator-Schnittstelle ähnlich dem Screenshot in Abbildung 18 aussehen.

Die konstruierte Abfrage-JOINs die Gastbuch-, Benutzerprofile- und aspnet_Users-Tabellen

Abbildung 18: Die konstruierte Abfrage JOIN enthält die GuestbookCommentsTabellen , UserProfilesund aspnet_Users (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Klicken Sie auf OK, um das Fenster Abfrage-Generator zu schließen und zum Bildschirm "Benutzerdefinierte Anweisungen oder gespeicherte Prozeduren definieren" zurückzukehren. Klicken Sie auf Weiter, um zum Bildschirm "Abfrage testen" zu gelangen. Dort können Sie die Abfrageergebnisse anzeigen, indem Sie auf die Schaltfläche Abfrage testen klicken. Wenn Sie bereit sind, klicken Sie auf Fertig stellen, um den Assistenten Datenquellen konfigurieren abzuschließen.

Als wir den Assistenten zum Konfigurieren von Datenquellen in Schritt 2 abgeschlossen haben, wurde die Auflistung des Fields zugehörigen DetailsView-Steuerelements aktualisiert, um ein BoundField für jede spalte zu enthalten, die SelectCommandvon zurückgegeben wird. Die ListView bleibt jedoch unverändert; Das Layout muss noch definiert werden. Das Layout der ListView kann manuell über das deklarative Markup oder über die Option "ListView konfigurieren" im smarten Tag erstellt werden. Normalerweise ziehe ich es vor, das Markup von Hand zu definieren, aber verwenden Sie eine beliebige Methode, die für Sie am natürlichsten ist.

Ich habe die folgenden LayoutTemplate, ItemTemplateund ItemSeparatorTemplate für mein ListView-Steuerelement verwendet:

<asp:ListView ID="CommentList" runat="server" DataSourceID="CommentsDataSource">

     <LayoutTemplate>
          <span ID="itemPlaceholder" runat="server" />
          <p>
               <asp:DataPager ID="DataPager1" runat="server">

                    <Fields>
                         <asp:NextPreviousPagerField ButtonType="Button" 
                              ShowFirstPageButton="True"
                              ShowLastPageButton="True" />
                    </Fields>
               </asp:DataPager>

          </p>
     </LayoutTemplate>
     <ItemTemplate>
          <h4>
               <asp:Label ID="SubjectLabel" runat="server" 
                    Text='<%# Eval("Subject") %>' />

          </h4>
          <asp:Label ID="BodyLabel" runat="server" 
               Text='<%# Eval("Body").ToString().Replace(Environment.NewLine, "<br />") %>' />
          <p>

          ---<br />
          <asp:Label ID="SignatureLabel" Font-Italic="true" runat="server"
               Text='<%# Eval("Signature") %>' />

          <br />
          <br />
          My Home Town:
          <asp:Label ID="HomeTownLabel" runat="server" 
               Text='<%# Eval("HomeTown") %>' />

          <br />
          My Homepage:
          <asp:HyperLink ID="HomepageUrlLink" runat="server" 
               NavigateUrl='<%# Eval("HomepageUrl") %>' 
               Text='<%# Eval("HomepageUrl") %>' />

          </p>
          <p align="center">
          Posted by
          <asp:Label ID="UserNameLabel" runat="server" 
               Text='<%# Eval("UserName") %>' /> 

          on
          <asp:Label ID="CommentDateLabel" runat="server" 
               Text='<%# Eval("CommentDate") %>' />
          </p>
     </ItemTemplate>

     <ItemSeparatorTemplate>
          <hr />
     </ItemSeparatorTemplate>
</asp:ListView>

Definiert LayoutTemplate das vom -Steuerelement ausgegebene Markup, während die ItemTemplate jedes von SqlDataSource zurückgegebene Element rendert. Das ItemTemplateresultierende Markup wird im LayoutTemplate-Steuerelement des -Steuerelements itemPlaceholder platziert. Zusätzlich zu itemPlaceholderenthält das LayoutTemplate ein DataPager-Steuerelement, das die ListView auf die Anzeige von nur 10 Gastbuchkommentaren pro Seite (standard) beschränkt und eine Pagingschnittstelle rendert.

My ItemTemplate zeigt den Betreff jedes Gästebuchkommentars in einem <h4> Element an, dessen Text sich unterhalb des Betreffs befindet. Beachten Sie, dass die syntax für die Anzeige des Textkörpers die von der Eval("Body") Datenbindungsanweisung zurückgegebenen Daten übernimmt, sie in eine Zeichenfolge konvertiert und Zeilenumbrüche durch das <br /> -Element ersetzt. Diese Konvertierung ist erforderlich, um die Zeilenumbrüche anzuzeigen, die beim Übermitteln des Kommentars eingegeben wurden, da Leerzeichen von HTML ignoriert werden. Die Signatur des Benutzers wird kursiv unter dem Text angezeigt, gefolgt von der Heimatstadt des Benutzers, einem Link zu seiner Homepage, dem Datum und der Uhrzeit des Kommentars und dem Benutzernamen der Person, die den Kommentar verlassen hat.

Nehmen Sie sich einen Moment Zeit, um die Seite über einen Browser anzuzeigen. Die Kommentare, die Sie dem Gästebuch in Schritt 5 hinzugefügt haben, sollten hier angezeigt werden.

Guestbook.aspx zeigt jetzt die Kommentare des Gästebuchs an.

Abbildung 19: Guestbook.aspx Zeigt jetzt die Kommentare des Gästebuchs an (Klicken, um das bild in voller Größe anzuzeigen)

Versuchen Sie, dem Gästebuch einen neuen Kommentar hinzuzufügen. Wenn Sie auf die PostCommentButton Schaltfläche klicken, wird die Seite zurückgeschrieben, und der Kommentar wird der Datenbank hinzugefügt, aber das ListView-Steuerelement wird nicht aktualisiert, um den neuen Kommentar anzuzeigen. Dies kann durch folgendes behoben werden:

  • Aktualisieren des Ereignishandlers Click der PostCommentButton Schaltfläche so, dass die Methode des DataBind() ListView-Steuerelements aufgerufen wird, nachdem der neue Kommentar in die Datenbank eingefügt wurde, oder
  • Festlegen der Eigenschaft des EnableViewState ListView-Steuerelements auf False. Dieser Ansatz funktioniert, da es durch Deaktivieren des Ansichtszustands des Steuerelements bei jedem Postback erneut an die zugrunde liegenden Daten gebunden werden muss.

Die Tutorialwebsite, die aus diesem Tutorial heruntergeladen werden kann, veranschaulicht beide Techniken. Die Eigenschaft des ListView-Steuerelements EnableViewState an False und der Code, der zum programmgesteuerten Erneuten Binden der Daten an die ListView erforderlich ist, ist im Click Ereignishandler vorhanden, wird jedoch auskommentiert.

Hinweis

Derzeit ermöglicht die AdditionalUserInfo.aspx Seite dem Benutzer das Anzeigen und Bearbeiten seiner Heimat-, Homepage- und Signatureinstellungen. Es kann schön sein, zu aktualisieren AdditionalUserInfo.aspx , um die Gästebuchkommentare des angemeldeten Benutzers anzuzeigen. Das heißt, neben der Überprüfung und Änderung ihrer Informationen kann ein Benutzer die AdditionalUserInfo.aspx Seite besuchen, um zu sehen, welche Gästebuchkommentare er in der Vergangenheit gemacht hat. Ich belasse dies als Übung für den interessierten Leser.

Schritt 6: Anpassen des CreateUserWizard-Steuerelements, um eine Schnittstelle für den Heimatort, die Homepage und die Signatur einzuschließen

Die SELECT von der Guestbook.aspx Seite verwendete Abfrage verwendet ein INNER JOIN , um die zugehörigen Datensätze zwischen den GuestbookCommentsTabellen , UserProfilesund aspnet_Users zu kombinieren. Wenn ein Benutzer, der keinen Datensatz enthält UserProfiles , einen Gastbuchkommentar erstellt, wird der Kommentar nicht in der ListView angezeigt, da nur INNER JOIN Datensätze zurückgegeben GuestbookComments werden, wenn übereinstimmende Datensätze in UserProfiles und aspnet_Usersvorhanden sind. Und wie wir in Schritt 3 gesehen haben, kann ein Benutzer, der keinen Datensatz enthält UserProfiles , seine Einstellungen auf der AdditionalUserInfo.aspx Seite nicht anzeigen oder bearbeiten.

Unnötig zu sagen, dass es aufgrund unserer Entwurfsentscheidungen wichtig ist, dass jedes Benutzerkonto im Mitgliedschaftssystem über einen übereinstimmenden Datensatz in der UserProfiles Tabelle verfügt. Wir möchten, dass ein entsprechender Datensatz hinzugefügt UserProfiles wird, wenn ein neues Mitgliedschaftsbenutzerkonto über createUserWizard erstellt wird.

Wie im Tutorial Erstellen von Benutzerkonten erläutert, löst das CreateUserWizard-Steuerelement nach dem Erstellen des neuen Mitgliedsbenutzerkontos sein -Ereignis ausCreatedUser. Wir können einen Ereignishandler für dieses Ereignis erstellen, die UserId für den gerade erstellten Benutzer abrufen und dann einen Datensatz mit Standardwerten für die Spalten , HomepageUrlund Signature in die UserProfilesHomeTownTabelle einfügen. Darüber hinaus ist es möglich, den Benutzer zur Eingabe dieser Werte aufzufordern, indem die Schnittstelle des CreateUserWizard-Steuerelements so angepasst wird, dass sie zusätzliche TextBoxes enthält.

Zunächst sehen wir uns an, wie Sie der UserProfiles Tabelle im CreatedUser Ereignishandler eine neue Zeile mit Standardwerten hinzufügen. Anschließend erfahren Sie, wie Sie die Benutzeroberfläche des CreateUserWizard-Steuerelements so anpassen, dass sie zusätzliche Formularfelder einschließt, um den Heimatort, die Homepage und die Signatur des neuen Benutzers zu erfassen.

Hinzufügen einer Standardzeile zuUserProfiles

Im Tutorial Erstellen von Benutzerkonten haben wir der CreatingUserAccounts.aspx Seite im Membership Ordner ein CreateUserWizard-Steuerelement hinzugefügt. Damit das CreateUserWizard-Steuerelement bei der Erstellung eines Benutzerkontos einen Datensatz zur UserProfiles Tabelle hinzugibt, müssen wir die Funktionalität des CreateUserWizard-Steuerelements aktualisieren. Anstatt diese Änderungen an der CreatingUserAccounts.aspx Seite vorzunehmen, fügen wir stattdessen ein neues CreateUserWizard-Steuerelement zur Seite hinzu EnhancedCreateUserWizard.aspx und nehmen die Änderungen für dieses Tutorial dort vor.

Öffnen Sie die EnhancedCreateUserWizard.aspx Seite in Visual Studio, und ziehen Sie ein CreateUserWizard-Steuerelement aus der Toolbox auf die Seite. Legen Sie die Eigenschaft des ID CreateUserWizard-Steuerelements auf fest NewUserWizard. Wie im Tutorial Erstellen von Benutzerkonten erläutert, fordert die Standardbenutzeroberfläche von CreateUserWizard den Besucher zur Eingabe der erforderlichen Informationen auf. Sobald diese Informationen bereitgestellt wurden, erstellt das Steuerelement intern ein neues Benutzerkonto im Membership-Framework, ohne dass wir eine einzelne Codezeile schreiben müssen.

Das CreateUserWizard-Steuerelement löst während des Workflows eine Reihe von Ereignissen aus. Nachdem ein Besucher die Anforderungsinformationen bereitgestellt und das Formular übermittelt hat, löst das CreateUserWizard-Steuerelement zunächst sein CreatingUser Ereignis aus. Wenn während des Erstellungsprozesses ein Problem auftritt, wird das CreateUserError Ereignis ausgelöst. Wenn der Benutzer jedoch erfolgreich erstellt wurde, wird das CreatedUser Ereignis ausgelöst. Im Tutorial Erstellen von Benutzerkonten haben wir einen Ereignishandler für das CreatingUser Ereignis erstellt, um sicherzustellen, dass der angegebene Benutzername keine führenden oder nachgestellten Leerzeichen enthält und dass der Benutzername an keiner Stelle im Kennwort angezeigt wurde.

Um eine Zeile in der Tabelle für den UserProfiles gerade erstellten Benutzer hinzuzufügen, müssen wir einen Ereignishandler für das CreatedUser Ereignis erstellen. Zu dem Zeitpunkt, zu dem das CreatedUser Ereignis ausgelöst wurde, wurde das Benutzerkonto bereits im Mitgliedschaftsframework erstellt, sodass wir den UserId-Wert des Kontos abrufen können.

Erstellen Sie einen Ereignishandler für das NewUserWizardEreignis des -Ereignisses, CreatedUser und fügen Sie den folgenden Code hinzu:

Protected Sub NewUserWizard_CreatedUser(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.CreatedUser
     ' Get the UserId of the just-added user
     Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
     Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)

     ' Insert a new record into UserProfiles
     Dim connectionString As String = 

          ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString
     Dim insertSql As String = "INSERT INTO UserProfiles(UserId, HomeTown, HomepageUrl,
          Signature) VALUES(@UserId, @HomeTown, @HomepageUrl, @Signature)"

     Using myConnection As New SqlConnection(connectionString)
          myConnection.Open()
          Dim myCommand As New SqlCommand(insertSql, myConnection)
          myCommand.Parameters.AddWithValue("@UserId", newUserId)
          myCommand.Parameters.AddWithValue("@HomeTown", DBNull.Value)

          myCommand.Parameters.AddWithValue("@HomepageUrl", DBNull.Value)
          myCommand.Parameters.AddWithValue("@Signature", DBNull.Value)
          myCommand.ExecuteNonQuery()
          myConnection.Close()
     End Using
End Sub

Die oben genannten Codewesen, indem sie die UserId des gerade hinzugefügten Benutzerkontos abrufen. Dies wird erreicht, indem Sie die Membership.GetUser(username) -Methode verwenden, um Informationen zu einem bestimmten Benutzer zurückzugeben, und dann die -Eigenschaft zum Abrufen der ProviderUserKey UserId verwenden. Der vom Benutzer in das CreateUserWizard-Steuerelement eingegebene Benutzername ist über seine UserName -Eigenschaft verfügbar.

Als Nächstes wird der Verbindungszeichenfolge abgerufen Web.config und die INSERT -Anweisung angegeben. Die erforderlichen ADO.NET Objekte werden instanziiert und der Befehl ausgeführt. Der Code weist den @HomeTownParametern , @HomepageUrl, und @Signature eine DBNull instance zu, wodurch Datenbankwerte NULL für die HomeTownFelder , HomepageUrlund Signature eingefügt werden.

Besuchen Sie die EnhancedCreateUserWizard.aspx Seite über einen Browser, und erstellen Sie ein neues Benutzerkonto. Kehren Sie anschließend zu Visual Studio zurück, und untersuchen Sie den Inhalt der aspnet_Users Tabellen und UserProfiles (wie in Abbildung 12 dargestellt). Das neue Benutzerkonto sollte in aspnet_Users und eine entsprechende UserProfiles Zeile (mit NULL Werten für HomeTown, HomepageUrlund Signature) angezeigt werden.

Ein neues Benutzerkonto und ein neuer UserProfiles-Datensatz wurden hinzugefügt.

Abbildung 20: Ein neues Benutzerkonto und UserProfiles datensatz wurden hinzugefügt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Nachdem der Besucher seine neuen Kontoinformationen angegeben und auf die Schaltfläche "Benutzer erstellen" geklickt hat, wird das Benutzerkonto erstellt und eine Zeile zur UserProfiles Tabelle hinzugefügt. Der CreateUserWizard zeigt CompleteWizardStepdann seine an, die eine Erfolgsmeldung und eine Schaltfläche Weiter anzeigt. Das Klicken auf die Schaltfläche Weiter führt zu einem Postback, aber es wird keine Aktion ausgeführt, sodass der Benutzer auf der EnhancedCreateUserWizard.aspx Seite hängen bleibt.

Wir können eine URL angeben, an die der Benutzer gesendet werden soll, wenn über die Eigenschaft des CreateUserWizard-Steuerelements ContinueDestinationPageUrlauf die Schaltfläche Weiter geklickt wird. Legen Sie die ContinueDestinationPageUrl Eigenschaft auf "~/Membership/AdditionalUserInfo.aspx" fest. Dies führt den neuen Benutzer zu AdditionalUserInfo.aspx, wo er seine Einstellungen anzeigen und aktualisieren kann.

Anpassen der CreateUserWizard-Schnittstelle zur Aufforderung zur Eingabe der Heimat, Homepage und Signatur des neuen Benutzers

Die Standardschnittstelle des CreateUserWizard-Steuerelements reicht für einfache Kontoerstellungsszenarien aus, in denen nur wichtige Benutzerkontoinformationen wie Benutzername, Kennwort und E-Mail erfasst werden müssen. Aber was wäre, wenn wir den Besucher auffordern wollten, ihren Heimatort, ihre Homepage und ihre Unterschrift einzugeben, während sie ihr Konto erstellen? Es ist möglich, die Schnittstelle des CreateUserWizard-Steuerelements anzupassen, um zusätzliche Informationen bei der CreatedUser Registrierung zu sammeln, und diese Informationen können im Ereignishandler verwendet werden, um zusätzliche Datensätze in die zugrunde liegende Datenbank einzufügen.

Das CreateUserWizard-Steuerelement erweitert das ASP.NET-Assistenten-Steuerelement. Hierbei handelt es sich um ein Steuerelement, das es einem Seitenentwickler ermöglicht, eine Reihe von geordneten WizardStepszu definieren. Das Wizard-Steuerelement rendert den aktiven Schritt und stellt eine Navigationsschnittstelle bereit, die es dem Besucher ermöglicht, diese Schritte zu durchlaufen. Das Wizard-Steuerelement ist ideal, um eine lange Aufgabe in mehrere kurze Schritte zu unterteilen. Weitere Informationen zum Assistentensteuerelement finden Sie unter Erstellen einer schrittweisen Benutzeroberfläche mit dem ASP.NET 2.0-Assistentensteuerelement.

Das Standardmarkup des CreateUserWizard-Steuerelements definiert zwei WizardSteps: CreateUserWizardStep und CompleteWizardStep.

<asp:CreateUserWizard ID="NewUserWizard" runat="server"
          ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">

          </asp:CreateUserWizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

Der erste WizardStep, CreateUserWizardSteprendert die Schnittstelle, die zur Eingabe des Benutzernamens, des Kennworts, der E-Mail usw. auffordert. Nachdem der Besucher diese Informationen zur Verfügung stellt und auf "Benutzer erstellen" klickt, wird der CompleteWizardStepangezeigt, der die Erfolgsmeldung und die Schaltfläche Weiter anzeigt.

Um die Schnittstelle des CreateUserWizard-Steuerelements so anzupassen, dass sie zusätzliche Formularfelder einschließt, können Wir Folgendes ausführen:

  • Erstellen einer oder mehrerer neuerWizardSteps, um die zusätzlichen Benutzeroberflächenelemente zu enthalten. Um dem CreateUserWizard ein neues WizardStep hinzuzufügen, klicken Sie im Smarttag auf den Link "Hinzufügen/Entfernen WizardStep s", um die WizardStep Sammlung Editor zu starten. Dort können Sie die Schritte im Assistenten hinzufügen, entfernen oder neu anordnen. Dies ist der Ansatz, den wir für dieses Tutorial verwenden werden.

  • Konvertieren derCreateUserWizardStepin eine bearbeitbareWizardStep. Dadurch wird der CreateUserWizardStep durch ein Äquivalent WizardStep ersetzt, dessen Markup eine Benutzeroberfläche definiert, die mit den CreateUserWizardStep-en übereinstimmt. Durch Konvertieren von CreateUserWizardStep in ein WizardStep können wir die Steuerelemente neu positionieren oder diesem Schritt zusätzliche Benutzeroberflächenelemente hinzufügen. Um den CreateUserWizardStep oder CompleteWizardStep in einen bearbeitbaren WizardStepZu konvertieren, klicken Sie im Smarttag des Steuerelements auf den Link "Benutzerschritt erstellen anpassen" oder "Vollständigen Schritt anpassen".

  • Verwenden Sie eine Kombination der beiden oben genannten Optionen.

Eine wichtige Sache, die Sie beachten sollten, ist, dass das CreateUserWizard-Steuerelement seinen Benutzerkontoerstellungsprozess ausführt, wenn auf die Schaltfläche "Benutzer erstellen" innerhalb des CreateUserWizardStep-Steuerelements geklickt wird. Es spielt keine Rolle, ob es zusätzliche WizardStep s nach dem CreateUserWizardStep gibt oder nicht.

Beim Hinzufügen einer benutzerdefinierten WizardStep zum CreateUserWizard-Steuerelement zum Sammeln zusätzlicher Benutzereingaben kann der benutzerdefinierte WizardStep vor oder nach dem CreateUserWizardStepplatziert werden. Wenn es vor dem CreateUserWizardStep kommt, ist die zusätzliche Benutzereingabe, die von der benutzerdefinierten WizardStep gesammelt wurde, für den CreatedUser Ereignishandler verfügbar. Wenn die Benutzerdefinierte WizardStep jedoch nach CreateUserWizardStep der Anzeige des Benutzerdefinierten WizardStep kommt, wurde das neue Benutzerkonto bereits erstellt, und das CreatedUser Ereignis wurde bereits ausgelöst.

Abbildung 21 zeigt den Workflow, wenn der hinzugefügte WizardStep vor dem CreateUserWizardStep- Da die zusätzlichen Benutzerinformationen zum Zeitpunkt des Auslösens des CreatedUser Ereignisses gesammelt wurden, müssen wir nur den CreatedUser Ereignishandler aktualisieren, um diese Eingaben abzurufen und diese für die Parameterwerte der INSERT Anweisung (statt DBNull.Value) zu verwenden.

Der CreateUserWizard-Workflow bei einem zusätzlichen AssistentenSchritt voran dem CreateUserWizardStep

Abbildung 21: Der CreateUserWizard-Workflow Wenn ein zusätzliches WizardStep vorangestellt wird (Klicken Sie, um dasCreateUserWizardStep bild in voller Größe anzuzeigen)

Wenn die Benutzerdefinierte WizardStepjedoch nachCreateUserWizardStepdem platziert wird, erfolgt der Prozess zum Erstellen eines Benutzerkontos, bevor der Benutzer die Möglichkeit hatte, seine Heimatstadt, homepage oder Unterschrift einzugeben. In einem solchen Fall müssen diese zusätzlichen Informationen nach dem Erstellen des Benutzerkontos in die Datenbank eingefügt werden, wie Abbildung 22 veranschaulicht.

Der CreateUserWizard-Workflow bei einem zusätzlichen AssistentenSchritt nach dem CreateUserWizardStep

Abbildung 22: Der CreateUserWizard-Workflow When an Additional WizardStep Comes After CreateUserWizardStep (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Der in Abbildung 22 dargestellte Workflow wartet auf das Einfügen eines Datensatzes in die UserProfiles Tabelle, bis Schritt 2 abgeschlossen ist. Wenn der Besucher nach Schritt 1 den Browser schließt, haben wir jedoch den Zustand erreicht, in dem ein Benutzerkonto erstellt wurde, aber kein Datensatz hinzugefügt UserProfileswurde. Eine Problemumgehung besteht darin, einen Datensatz mit NULL oder Standardwerten UserProfiles in den Ereignishandler eingefügt zu haben (der CreatedUser nach Schritt 1 ausgelöst wird), und diesen Datensatz nach Abschluss von Schritt 2 zu aktualisieren. Dadurch wird sichergestellt, dass ein UserProfiles Datensatz für das Benutzerkonto hinzugefügt wird, auch wenn der Benutzer den Registrierungsprozess zur Hälfte beendet.

Für dieses Tutorial erstellen wir eine neue WizardStep , die nach dem CreateUserWizardStep , aber vor dem CompleteWizardStepauftritt. Zunächst wird der WizardStep eingerichtet und konfiguriert, und dann sehen wir uns den Code an.

Wählen Sie im Smarttag des CreateUserWizard-Steuerelements die Option "Hinzufügen/EntfernenWizardStep" aus, wodurch das WizardStep Dialogfeld Sammlung Editor geöffnet wird. Fügen Sie ein neues WizardStephinzu, und legen Sie auf UserSettingsID fest, auf Title "Ihre Einstellungen" und auf StepTypeStep. Positionieren Sie es dann so, dass es nach dem CreateUserWizardStep ("Registrieren für Ihr neues Konto") und vor dem CompleteWizardStep ("Abgeschlossen") kommt, wie in Abbildung 23 dargestellt.

Hinzufügen eines neuen AssistentenSchritt zum CreateUserWizard-Steuerelement

Abbildung 23: Hinzufügen eines Neuen WizardStep zum CreateUserWizard-Steuerelement (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Klicken Sie auf OK, um das WizardStep Dialogfeld Sammlung Editor zu schließen. Das neue WizardStep wird durch das aktualisierte deklarative Markup des CreateUserWizard-Steuerelements belegt:

<asp:CreateUserWizard ID="NewUserWizard" runat="server"

          ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
          </asp:CreateUserWizardStep>
          <asp:WizardStep runat="server" ID="UserSettings" StepType="Step"

               Title="Your Settings">
          </asp:WizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

Beachten Sie das neue <asp:WizardStep> Element. Wir müssen die Benutzeroberfläche hinzufügen, um den Heimatort, die Homepage und die Signatur des neuen Benutzers hier zu erfassen. Sie können diesen Inhalt in der deklarativen Syntax oder über die Designer eingeben. Um die Designer zu verwenden, wählen Sie den Schritt "Ihre Einstellungen" aus der Dropdownliste im Smarttag aus, um den Schritt im Designer anzuzeigen.

Hinweis

Wenn Sie einen Schritt in der Dropdownliste des Smarttags auswählen, wird die Eigenschaft des CreateUserWizard-Steuerelements ActiveStepIndexaktualisiert, die den Index des Startschritts angibt. Wenn Sie diese Dropdownliste verwenden, um den Schritt "Ihre Einstellungen" im Designer zu bearbeiten, stellen Sie daher sicher, dass Sie ihn wieder auf "Registrieren für Ihr neues Konto" festlegen, damit dieser Schritt angezeigt wird, wenn Benutzer die EnhancedCreateUserWizard.aspx Seite zum ersten Mal besuchen.

Erstellen Sie eine Benutzeroberfläche im Schritt "Ihre Einstellungen", die drei TextBox-Steuerelemente mit den Namen HomeTown, HomepageUrlund Signatureenthält. Nach dem Erstellen dieser Schnittstelle sollte das deklarative Markup des CreateUserWizard wie folgt aussehen:

<asp:CreateUserWizard ID="NewUserWizard" runat="server"

          ContinueDestinationPageUrl="~/Membership/AdditionalUserInfo.aspx">
     <WizardSteps>
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
          </asp:CreateUserWizardStep>
          <asp:WizardStep runat="server" ID="UserSettings" StepType="Step"

                    Title="Your Settings">
               <p>
                    <b>Home Town:</b><br />
                    <asp:TextBox ID="HomeTown" runat="server"></asp:TextBox>

               </p>
               <p>
                    <b>Homepage URL:</b><br />
                    <asp:TextBox ID="HomepageUrl" Columns="40" runat="server"></asp:TextBox>

               </p>
               <p>
                    <b>Signature:</b><br />
                    <asp:TextBox ID="Signature" TextMode="MultiLine" Width="95%"

                         Rows="5" runat="server"></asp:TextBox>
               </p>
          </asp:WizardStep>
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">

          </asp:CompleteWizardStep>
     </WizardSteps>
</asp:CreateUserWizard>

Besuchen Sie diese Seite über einen Browser, erstellen Sie ein neues Benutzerkonto, indem Sie Werte für den Heimatort, die Homepage und die Signatur angeben. Nach abschluss des Abschlusses wird das CreateUserWizardStep Benutzerkonto im Membership-Framework erstellt und der CreatedUser Ereignishandler wird ausgeführt. Dadurch wird eine neue Zeile hinzugefügt UserProfiles, jedoch mit einem Datenbankwert NULL für HomeTown, HomepageUrlund Signature. Die für den Heimatort, die Homepage und die Signatur eingegebenen Werte werden nie verwendet. Das Nettoergebnis ist ein neues Benutzerkonto mit einem UserProfiles Datensatz, dessen HomeTownFelder , HomepageUrlund Signature noch angegeben werden müssen.

Wir müssen Code nach dem Schritt "Ihre Einstellungen" ausführen, der die vom Benutzer eingegebenen Heimat-, Honepage- und Signaturwerte übernimmt und den entsprechenden UserProfiles Datensatz aktualisiert. Jedes Mal, wenn der Benutzer zwischen den Schritten in einem Assistenten-Steuerelement wechselt, wird das Ereignis des ActiveStepChanged Assistenten ausgelöst. Wir können einen Ereignishandler für dieses Ereignis erstellen und die UserProfiles Tabelle aktualisieren, wenn der Schritt "Ihre Einstellungen" abgeschlossen ist.

Fügen Sie einen Ereignishandler für das CreateUserWizard-Ereignis ActiveStepChanged hinzu, und fügen Sie den folgenden Code hinzu:

Protected Sub NewUserWizard_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewUserWizard.ActiveStepChanged
     ' Have we JUST reached the Complete step?
     If NewUserWizard.ActiveStep.Title = "Complete" Then
          Dim UserSettings As WizardStep = CType(NewUserWizard.FindControl("UserSettings"),WizardStep)

          ' Programmatically reference the TextBox controls
          Dim HomeTown As TextBox = CType(UserSettings.FindControl("HomeTown"), TextBox)
          Dim HomepageUrl As TextBox = CType(UserSettings.FindControl("HomepageUrl"), TextBox)
          Dim Signature As TextBox = CType(UserSettings.FindControl("Signature"), TextBox)

          ' Update the UserProfiles record for this user
          ' Get the UserId of the just-added user
          Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
          Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)

          ' Insert a new record into UserProfiles
          Dim connectionString As String = ConfigurationManager.ConnectionStrings("SecurityTutorialsConnectionString").ConnectionString

          Dim updateSql As String = "UPDATE UserProfiles SET HomeTown = @HomeTown, HomepageUrl
               = @HomepageUrl, Signature = @Signature WHERE UserId = @UserId"

          Using myConnection As New SqlConnection(connectionString)
               myConnection.Open()
               Dim myCommand As New SqlCommand(updateSql, myConnection)
               myCommand.Parameters.AddWithValue("@HomeTown", HomeTown.Text.Trim())
               myCommand.Parameters.AddWithValue("@HomepageUrl", HomepageUrl.Text.Trim())
               myCommand.Parameters.AddWithValue("@Signature", Signature.Text.Trim())

               myCommand.Parameters.AddWithValue("@UserId", newUserId)
               myCommand.ExecuteNonQuery()
               myConnection.Close()
          End Using
     End If
End Sub

Der obige Code beginnt mit der Feststellung, ob wir gerade den Schritt "Abgeschlossen" erreicht haben. Da der Schritt "Abgeschlossen" unmittelbar nach dem Schritt "Ihre Einstellungen" erfolgt, bedeutet das, dass der Besucher gerade den Schritt "Ihre Einstellungen" beendet hat, wenn der Besucher den Schritt "Abgeschlossen" erreicht.

In einem solchen Fall müssen wir programmgesteuert auf die TextBox-Steuerelemente innerhalb von UserSettings WizardStepverweisen. Dies wird erreicht, indem zuerst die FindControl -Methode verwendet wird, um programmgesteuert auf zu UserSettings WizardStepverweisen, und dann erneut, um auf die TextBoxes innerhalb von WizardStepzu verweisen. Nachdem auf die TextBoxes verwiesen wurde, können wir die UPDATE Anweisung ausführen. Die UPDATE -Anweisung verfügt über die gleiche Anzahl von Parametern wie die INSERT -Anweisung im CreatedUser Ereignishandler, aber hier verwenden wir die vom Benutzer angegebenen Werte für den Heimatort, die Homepage und die Signatur.

Wenn dieser Ereignishandler vorhanden ist, besuchen Sie die EnhancedCreateUserWizard.aspx Seite über einen Browser, und erstellen Sie ein neues Benutzerkonto, das Werte für den Heimatort, die Homepage und die Signatur angibt. Nach dem Erstellen des neuen Kontos sollten Sie auf die Seite weitergeleitet werden, auf der AdditionalUserInfo.aspx die gerade eingegebenen Heimatorte, die Startseite und die Signaturinformationen angezeigt werden.

Hinweis

Unsere Website verfügt derzeit über zwei Seiten, von denen aus ein Besucher ein neues Konto erstellen kann: CreatingUserAccounts.aspx und EnhancedCreateUserWizard.aspx. Die Sitemap und Anmeldeseite der Website zeigen auf die CreatingUserAccounts.aspx Seite, aber die CreatingUserAccounts.aspx Seite fordert den Benutzer nicht zur Eingabe seiner Heimat-, Homepage- und Signaturinformationen auf und fügt keine entsprechende Zeile hinzu UserProfiles. Aktualisieren Sie daher entweder die CreatingUserAccounts.aspx Seite so, dass sie diese Funktionalität bietet, oder aktualisieren Sie die Sitemap und die Anmeldeseite so, dass anstelle von CreatingUserAccounts.aspxverwiesen EnhancedCreateUserWizard.aspx wird. Wenn Sie die letzte Option auswählen, müssen Sie die Datei des Membership Ordners Web.config aktualisieren, um anonymen Benutzern den Zugriff auf die EnhancedCreateUserWizard.aspx Seite zu ermöglichen.

Zusammenfassung

In diesem Tutorial haben wir techniken zum Modellieren von Daten untersucht, die sich auf Benutzerkonten innerhalb des Mitgliedschaftsframeworks beziehen. Insbesondere haben wir uns mit Modellierungsentitäten befasst, die eine 1:n-Beziehung mit Benutzerkonten sowie Daten gemeinsam mit einer 1:1-Beziehung nutzen. Darüber hinaus haben wir gesehen, wie diese verwandten Informationen angezeigt, eingefügt und aktualisiert werden können, wobei einige Beispiele das SqlDataSource-Steuerelement und andere mithilfe ADO.NET Code verwenden.

Dieses Tutorial schließt unseren Blick auf Benutzerkonten ab. Ab dem nächsten Tutorial widmen wir uns den Rollen. In den nächsten Tutorials sehen wir uns das Rollenframework an, erfahren, wie sie neue Rollen erstellen, Benutzern Rollen zuweisen, wie sie bestimmen, zu welchen Rollen ein Benutzer gehört und wie die rollenbasierte Autorisierung angewendet wird.

Viel Spaß beim Programmieren!

Weitere Informationen

Weitere Informationen zu den in diesem Tutorial erläuterten Themen finden Sie in den folgenden Ressourcen:

Zum Autor

Scott Mitchell, Autor mehrerer ASP/ASP.NET-Bücher 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. Scott kann unter mitchell@4guysfromrolla.com oder über seinen Blog unter http://ScottOnWriting.NETerreicht werden.

Besonderer Dank an...

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter ab mitchell@4GuysFromRolla.com.