Speichern von zusätzlichen Benutzerinformationen (C#)
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 Platform anstelle der Mitgliedschaftsanbieter verwenden, die zum Zeitpunkt der Veröffentlichung dieses Artikels vorgestellt wurden. ASP.NET Identity hat 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 für anspruchsbasierte Identitäten
- Bessere Interoperabilität mit ASP.Net Core
Code herunterladen oder PDF herunterladen
In diesem Tutorial beantworten wir diese Frage, indem wir eine sehr rudimentäre Gästebuchanwendung erstellen. Dabei sehen wir uns verschiedene Optionen zum Modellieren von Benutzerinformationen in einer Datenbank an und erfahren dann, wie diese Daten den benutzerkonten zugeordnet werden, die vom Mitgliedschaftsframework erstellt wurden.
Einführung
ASP. Das Mitgliedschaftsframework von NET bietet eine flexible Benutzeroberfläche zum Verwalten von Benutzern. Die Mitgliedschafts-API umfasst u. a. 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 Benutzerkontoaufgaben erforderlich sind. Dies wird durch die Methoden und Eigenschaften der MembershipUser
-Klasse belegt, die ein Benutzerkonto im Membership-Framework modelliert. Diese Klasse verfügt über Eigenschaften wie UserName
, Email
und IsLockedOut
, und Methoden wie GetPassword
und UnlockUser
.
Häufig müssen Anwendungen zusätzliche Benutzerinformationen speichern, die nicht im Mitgliedschaftsframework enthalten sind. Ein Onlinehändler muss beispielsweise jedem Benutzer die Möglichkeit geben, seine Liefer- und Rechnungsadressen, Zahlungsinformationen, Lieferpräferenzen und Telefonnummern zu speichern. Darüber hinaus ist jede Bestellung im System einem bestimmten Benutzerkonto zugeordnet.
Die MembershipUser
-Klasse enthält keine Eigenschaften wie PhoneNumber
oder DeliveryPreferences
PastOrders
. Wie verfolgen wir also die von der Anwendung benötigten Benutzerinformationen und lassen sie in das Mitgliedschaftsframework integrieren? In diesem Tutorial beantworten wir diese Frage, indem wir eine sehr rudimentäre Gästebuchanwendung erstellen. Dabei sehen wir uns verschiedene Optionen zum Modellieren von Benutzerinformationen in einer Datenbank an und erfahren dann, wie diese Daten den benutzerkonten zugeordnet werden, die vom Mitgliedschaftsframework erstellt wurden. 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 den benutzerkonten zuzuordnen, die vom Mitgliedschaftsframework erstellt wurden. Um diese Techniken zu veranschaulichen, müssen wir die Tutorialwebanwendung so erweitern, dass sie eine Art von benutzerbezogenen Daten erfasst. (Derzeit enthält das Datenmodell der Anwendung nur die Anwendungsdiensttabellen, die SqlMembershipProvider
von benötigt werden.)
Wir erstellen eine sehr einfache Gästebuchanwendung, in der ein authentifizierter Benutzer einen Kommentar hinterlassen kann. Zusätzlich zum Speichern von Gästebuchkommentaren können wir jedem Benutzer erlauben, seine Heimatstadt, Homepage und Signatur zu speichern. Falls angegeben, werden die Heimat, die Homepage und die Unterschrift des Benutzers auf jeder Nachricht angezeigt, die er im Gästebuch hinterlassen hat.
Hinzufügen derGuestbookComments
Tabelle
Um die Gästebuchkommentare zu erfassen, müssen wir eine Datenbanktabelle mit dem Namen GuestbookComments
erstellen, die Spalten wie CommentId
, Subject
, Body
und CommentDate
enthält. Außerdem muss jeder Datensatz in der GuestbookComments
Tabelle auf den Benutzer verweisen, der den Kommentar hinterlassen hat.
Um diese Tabelle zu unserer Datenbank hinzuzufügen, wechseln Sie in Visual Studio zum Explorer Datenbank, und führen Sie einen Drilldown in die SecurityTutorials
Datenbank durch. 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.
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 GuestbookComments
Spalten des . Fügen Sie zunächst eine Spalte mit dem Namen CommentId
des Typs uniqueidentifier
hinzu. 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 in jedem INSERT
anzugeben, können wir angeben, dass automatisch ein neuer uniqueidentifier
Wert für dieses Feld INSERT
für generiert werden soll, indem wir den Standardwert der Spalte auf NEWID()
festlegen. Nachdem Sie dieses erste Feld hinzugefügt, es als Primärschlüssel markiert und dessen Standardwert festgelegt haben, sollte ihr Bildschirm ähnlich wie in Abbildung 2 dargestellt aussehen.
Abbildung 2: Hinzufügen einer primären Spalte mit dem Namen 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 Body
Namen vom Typ nvarchar(MAX)
hinzu, und heben Sie die Streuung NULL
von s in beiden Spalten auf. Fügen Sie anschließend eine Spalte mit dem Namen CommentDate
vom Typ datetime
hinzu. 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 zuordnet. Eine Möglichkeit 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 SqlMembershipProvider
verwenden. Wenn Sie jedoch verwenden SqlMembershipProvider
, wie in dieser Tutorialreihe, ist die UserName
Spalte in der aspnet_Users
Tabelle nicht garantiert eindeutig. Der aspnet_Users
Primärschlüssel der Tabelle ist UserId
und vom Typ uniqueidentifier
. Aus diesem Grund benötigt die GuestbookComments
Tabelle eine Spalte mit dem Namen UserId
des Typs uniqueidentifier
(nicht zulässige NULL
Werte). 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 über zwei (oder mehr) Datensätze mit demselben UserName
Wert verfügt. 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. Geben Sie der neuen Tabelle GuestbookComments
den Namen .
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 der Symbolleiste auf das Symbol Beziehung, 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.
Abbildung 3: Verwenden des Dialogfelds Fremdschlüsselbeziehungen zum Verwalten der Fremdschlüsseleinschränkungen einer Tabelle (Klicken Sie hier, um das Bild in voller Größe 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.
Abbildung 4: Einrichten einer Fremdschlüsseleinschränkung zwischen den aspnet_Users
Tabellen 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 nie ein Gastbucheintrag vorhanden ist, 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. Anders ausgedrückt: Wir können diese Fremdschlüsseleinschränkung so einrichten, dass die Gastbucheinträge eines Benutzers automatisch gelöscht werden, wenn ihr Benutzerkonto gelöscht wird. Erweitern Sie hierzu den Abschnitt "INSERT And UPDATE Specification", und legen Sie die Eigenschaft "Delete Rule" auf Cascade fest.
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 in der Symbolleiste auf das Symbol Speichern, um die Tabelle und diese Beziehung zu speichern.
Speichern von Heimatort, Homepage und Signatur des Benutzers
Die GuestbookComments
Tabelle veranschaulicht, wie Informationen gespeichert werden, die eine 1:n-Beziehung mit Benutzerkonten gemeinsam verwenden. Da jedes Benutzerkonto über eine beliebige Anzahl von zugeordneten Kommentaren verfügen kann, 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. Wenn Sie verwenden SqlMembershipProvider
, wird dieser Link am besten hergestellt, indem Sie eine Spalte mit dem Namen des UserId
Typs uniqueidentifier
und eine Fremdschlüsseleinschränkung zwischen dieser Spalte und aspnet_Users.UserId
erstellen.
Nun müssen wir 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:
Hinzufügen neuer Spalten zum
aspnet_Users
Oderaspnet_Membership
Tabellen. Ich würde diesen Ansatz nicht empfehlen, da er das schema ändert, dasSqlMembershipProvider
von verwendet wird. Diese Entscheidung kann Sie auf der Straße heimgesucht haben. Was geschieht beispielsweise, wenn eine zukünftige Version von ASP.NET ein anderesSqlMembershipProvider
Schema verwendet. Microsoft kann ein Tool zum Migrieren der ASP.NET 2.0-DatenSqlMembershipProvider
in das neue Schema einschließen, aber wenn Sie das ASP.NET 2.0-SchemaSqlMembershipProvider
geändert haben, ist eine solche Konvertierung möglicherweise nicht möglich.Verwenden Sie ASP. NET's Profile Framework, 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 konzipiert ist. Wie das Mitgliedschaftsframework wird das Profilframework auf dem Anbietermodell erstellt. Die .NET Framework mit einem
SqlProfileProvider
Sthat geliefert wird, speichert Profildaten in einer SQL Server-Datenbank. Tatsächlich verfügt unsere Datenbank bereits über die vonSqlProfileProvider
(aspnet_Profile
) verwendete Tabelle, da sie hinzugefügt wurde, als wir die Anwendungsdienste im Tutorial Erstellen des Mitgliedschaftsschemas in SQL Server hinzugefügt haben.
Der Standard Vorteil des Profile-Frameworks besteht darin, dass Entwickler die Profileigenschaften inWeb.config
definieren können– es muss kein Code geschrieben werden, um die Profildaten in 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 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 dieSqlProfileProvider
Profileigenschaften in einer stark denormalisierten Weise, sodass es so gut wie unmöglich ist, Abfragen direkt gegen 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 und
aspnet_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 namens, 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
. Zulassen von NULL
Werten, 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 hinzu nvarchar(500)
. Jede dieser drei Spalten kann einen NULL
Wert akzeptieren.
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 kaskadieren. 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. Diese Art von Beziehung wird als 1:1 bezeichnet.
Nachdem wir nun das Datenmodell erstellt haben, können wir es verwenden. In Den Schritten 2 und 3 wird erläutert, wie der aktuell angemeldete Benutzer seine Heimatort-, 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 dem aktuell angemeldeten Benutzer das Anzeigen und Bearbeiten seiner Heimatort-, Homepage- und Signaturinformationen zu ermöglichen. Wir können 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
die Anweisungen auszuführen, können wir ADO.NET Code in der CodeBehind-Klasse unserer Seite schreiben oder alternativ einen deklarativen Ansatz mit der SqlDataSource verwenden. Im Idealfall enthält unsere Anwendung eine mehrstufige Architektur, die entweder programmgesteuert von der CodeBehind-Klasse der Seite oder deklarativ über das ObjectDataSource-Steuerelement aufgerufen werden könnte.
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 auf der ASP.NET-Seite bevorzugt wird. Ich werde die Verwendung von DetailsView und SqlDataSource – die schnellste und einfachste Option – durchgehen, 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
aus. Erweitern Sie das Smarttag von DetailsView, und binden Sie es an ein neues Datenquellensteuerelement. 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 Datenbanksymbol aus, und geben Sie als an ID
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 für Web.config
die SecurityTutorials
Datenbank definiert. Dieser Verbindungszeichenfolgenname – SecurityTutorialsConnectionString
sollte sich in der Dropdownliste befinden. Wählen Sie diese Option aus, und klicken Sie auf Weiter.
Abbildung 8: Auswählen SecurityTutorialsConnectionString
aus der Drop-Down-Liste (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Auf dem folgenden Bildschirm werden wir aufgefordert, die abzufragende Tabelle und die zu abfragenden Spalten anzugeben. Wählen Sie die UserProfiles
Tabelle aus der Dropdownliste aus, und überprüfen Sie alle Spalten.
Abbildung 9: Wiederherstellen 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 UserProfiles
zurück, aber wir interessieren uns nur für den aktuell angemeldeten Benutzerdatensatz. Um eine WHERE
Klausel hinzuzufügen, klicken Sie auf die WHERE
Schaltfläche, um das Dialogfeld Klausel hinzufügen zu WHERE
öffnen (siehe Abbildung 10). Hier können Sie die Spalte zum Filtern, den Operator und die Quelle des Filterparameters auswählen. Wählen Sie als Spalte und "=" als Operator aus UserId
.
Leider gibt es keine integrierte Parameterquelle, die den Wert des UserId
aktuell angemeldeten Benutzers zurückgibt. 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.
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, kehren Sie zu dem in Abbildung 9 gezeigten Bildschirm zurück. Dieses Mal sollte die SQL-Abfrage am unteren Bildschirmrand jedoch eine WHERE
Klausel enthalten. Klicken Sie auf Weiter, um zum Bildschirm "Abfrage testen" 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 fügt es BoundFields manuell zur DetailsView für jede Spalte hinzu, die von sqlDataSource SelectCommand
zurü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 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 UserId
festlegen, 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 void UserProfileDataSource_Selecting(object sender,
SqlDataSourceSelectingEventArgs e)
{
// Get a reference to the currently logged on user
MembershipUser currentUser = Membership.GetUser();
// Determine the currently logged on user's UserId value
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Assign the currently logged on user's UserId to the @UserId parameter
e.Command.Parameters["@UserId"].Value = currentUserId;
}
Der obige Code ruft zunächst einen Verweis auf den aktuell angemeldeten Benutzer ab, indem die -Methode der Membership
-Klasse GetUser
aufgerufen wird. Dadurch wird ein MembershipUser
-Objekt zurückgegeben, dessen ProviderUserKey
-Eigenschaft das UserId
enthält. Der UserId
Wert wird dann dem SqlDataSource-Parameter @UserId
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 null
. In einem solchen Fall führt dies zu einem NullReferenceException
in der folgenden Codezeile, wenn versucht wird, die ProviderUserKey
Eigenschaft zu lesen. Natürlich müssen wir uns nicht um Membership.GetUser()
die Rückgabe eines null
Werts auf der AdditionalUserInfo.aspx
Seite kümmern, 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 ein Nichtobjektnull MembershipUser
von der GetUser()
-Methode zurückgegeben wird, bevor Sie auf ihre Eigenschaften verweisen.
Wenn Sie die AdditionalUserInfo.aspx
Seite über einen Browser besuchen, wird eine leere Seite angezeigt, da der Tabelle noch keine Zeilen UserProfiles
hinzugefügt wurden. In Schritt 6 wird erläutert, wie Sie das CreateUserWizard-Steuerelement anpassen, um der UserProfiles
Tabelle automatisch eine neue Zeile hinzuzufügen, 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 Tabelle aus UserProfiles
. Abbildung 11 zeigt diese Ergebnisse, wenn sie vertikal gekachelt 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.
Abbildung 11: Der Inhalt der aspnet_Users
Tabellen und UserProfiles
der Tabellen werden 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 HomeTown
Felder , HomepageUrl
und 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 UserProfiles
einzufügen. Abbildung 12 zeigt die UserProfiles
Tabelle, nachdem ein neuer Datensatz für Bruce hinzugefügt wurde.
Abbildung 12: Ein Datensatz wurde für Bruce hinzugefügt UserProfiles
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Kehren Sie zur Seite zurück, die AdditionalUserInfo.aspx
als Bruce angemeldet ist. Wie Abbildung 13 zeigt, werden Bruces 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 Befehls- und 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.
Abbildung 14: Angeben der SqlDataSource und UpdateCommand
UpdateParameters
(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 Edit
festlegen.
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 UserProfiles
verfügt, werden die Einstellungen des Benutzers in einer bearbeitbaren Benutzeroberfläche angezeigt.
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 SettingsUpdatedMessage
ID
, 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 void UserProfile_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
{
SettingsUpdatedMessage.Visible = true;
}
Kehren Sie über einen Browser zur AdditionalUserInfo.aspx
Seite zurück, und aktualisieren Sie die Daten. Dieses Mal wird eine hilfreiche status Meldung angezeigt.
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 Edit
festgelegt 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.
Hinzufügen eines Links zurAdditionalUserInfo.aspx
Seite in der Gestaltungsvorlage
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 Body
fest, Width
TextMode
und MultiLine
legen 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 InsertCommand
konfigurieren 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. using System.Data.SqlClient;
).
Erstellen Sie einen Ereignishandler für das PostCommentButton
-Ereignis, Click
und fügen Sie den folgenden Code hinzu:
protected void PostCommentButton_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
return;
// Determine the currently logged on user's UserId
MembershipUser currentUser = Membership.GetUser();
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Insert a new record into GuestbookComments
string connectionString =
ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
string insertSql = "INSERT INTO GuestbookComments(Subject, Body, UserId) VALUES(@Subject,
@Body, @UserId)";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
myConnection.Open();
SqlCommand myCommand = 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();
}
// "Reset" the Subject and Body TextBoxes
Subject.Text = string.Empty;
Body.Text = string.Empty;
}
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 GuestbookComments
einen -Wert verwendet werden muss.
Anschließend wird die 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 GuestbookComments
hinzugefü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.
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 GuestbookComments
Tabellen , UserProfiles
und 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 GuestbookComments
Tabellen , UserProfiles
und 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 , Body
und CommentDate
aus. Geben Sie die HomeTown
Spalten , HomepageUrl
und Signature
aus der UserProfiles
Tabelle zurück, und geben Sie von zurück UserName
aspnet_Users
.Subject
GuestbookComments
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.
Abbildung 18: Die konstruierte Abfrage JOIN
enthält die GuestbookComments
Tabellen , UserProfiles
und 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 SelectCommand
von 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
, ItemTemplate
und 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 ItemTemplate
resultierende Markup wird im LayoutTemplate
-Steuerelement des -Steuerelements itemPlaceholder
platziert. Zusätzlich zu itemPlaceholder
enthä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.
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
derPostCommentButton
Schaltfläche so, dass die Methode desDataBind()
ListView-Steuerelements aufgerufen wird, nachdem der neue Kommentar in die Datenbank eingefügt wurde, oder - Festlegen der Eigenschaft des
EnableViewState
ListView-Steuerelements auffalse
. 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 GuestbookComments
Tabellen , UserProfiles
und 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_Users
vorhanden 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 , HomepageUrl
und Signature
in die UserProfiles
HomeTown
Tabelle 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 NewUserWizard
Ereignis des -Ereignisses, CreatedUser
und fügen Sie den folgenden Code hinzu:
protected void NewUserWizard_CreatedUser(object sender, EventArgs e)
{
// Get the UserId of the just-added user
MembershipUser newUser = Membership.GetUser(NewUserWizard.UserName);
Guid newUserId = (Guid)newUser.ProviderUserKey;
// Insert a new record into UserProfiles
string connectionString =
ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
string insertSql = "INSERT INTO UserProfiles(UserId, HomeTown, HomepageUrl,
Signature) VALUES(@UserId, @HomeTown, @HomepageUrl, @Signature)";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
myConnection.Open();
SqlCommand myCommand = 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();
}
}
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 die Verbindungszeichenfolge von Web.config
abgerufen, und die INSERT
-Anweisung wird angegeben. Die erforderlichen ADO.NET Objekte werden instanziiert und der Befehl ausgeführt. Der Code weist den @HomeTown
Parametern , @HomepageUrl
, und @Signature
eine DBNull
instance zu, wodurch Datenbankwerte NULL
für die HomeTown
Felder , HomepageUrl
und 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
, HomepageUrl
und Signature
) angezeigt werden.
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 CompleteWizardStep
dann seine an, die eine Erfolgsmeldung und eine Schaltfläche Weiter anzeigt. Wenn Sie auf die Schaltfläche Weiter klicken, wird ein Postback verursacht, 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 ContinueDestinationPageUrl
auf die Schaltfläche Weiter geklickt wird. Legen Sie die ContinueDestinationPageUrl
-Eigenschaft auf "~/Membership/AdditionalUserInfo.aspx" fest. Dadurch wird der neue Benutzer zu gelangen, AdditionalUserInfo.aspx
wo er seine Einstellungen anzeigen und aktualisieren kann.
Anpassen der CreateUserWizard-Benutzeroberfläche zur Aufforderung zur Eingabe von Heimatort, 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, seine Heimat, Homepage und Unterschrift einzugeben, während er sein Konto erstellt? Es ist möglich, die Schnittstelle des CreateUserWizard-Steuerelements anzupassen, um zusätzliche Informationen bei der CreatedUser
Registrierung zu sammeln. 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-Assistent-Steuerelement, bei dem es sich um ein Steuerelement handelt, das es einem Seitenentwickler ermöglicht, eine Reihe von geordneten WizardSteps
zu definieren. Das Assistent-Steuerelement rendert den aktiven Schritt und stellt eine Navigationsoberfläche bereit, die es dem Besucher ermöglicht, diese Schritte zu durchlaufen. Das Assistentensteuerelement eignet sich ideal, um eine lange Aufgabe in mehrere kurze Schritte zu unterteilen. Weitere Informationen zum Assistenten-Steuerelement 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
, CreateUserWizardStep
rendert die Schnittstelle, die zur Eingabe von Benutzername, Kennwort, E-Mail usw. auffordert. Nachdem der Besucher diese Informationen bereitgestellt hat und auf "Benutzer erstellen" klickt, wird ihr der CompleteWizardStep
angezeigt, der die Erfolgsmeldung und die Schaltfläche "Weiter" anzeigt.
Um die Schnittstelle des CreateUserWizard-Steuerelements so anzupassen, dass sie zusätzliche Formularfelder enthält, können wir:
Erstellen einer oder mehrerer neuer
WizardStep
s, um die zusätzlichen Benutzeroberflächenelemente zu enthalten. Um dem CreateUserWizard ein neuesWizardStep
hinzuzufügen, klicken Sie im zugehörigen Smarttag auf den Link "Hinzufügen/EntfernenWizardSteps
", um denWizardStep
Sammlungs-Editor zu starten. Von dort aus 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 von
CreateUserWizardStep
in eine bearbeitbareWizardStep
. Dadurch wird durchCreateUserWizardStep
ein ÄquivalentWizardStep
ersetzt, dessen Markup eine Benutzeroberfläche definiert, die mit denCreateUserWizardStep
-Elementen übereinstimmt. Durch Konvertieren vonCreateUserWizardStep
in könnenWizardStep
wir die Steuerelemente neu positionieren oder diesem Schritt zusätzliche Benutzeroberflächenelemente hinzufügen. Klicken Sie im Smarttag desCreateUserWizardStep
CompleteWizardStep
Steuerelements auf den Link "Benutzerschritt erstellen anpassen" oder "Vollständigen Schritt anpassen", um oder in eine bearbeitbareWizardStep
Datei zu konvertieren.Verwenden Sie eine Kombination der beiden oben genannten Optionen.
Eine wichtige Sache zu beachten ist, dass das CreateUserWizard-Steuerelement seinen Benutzerkontoerstellungsprozess ausführt, wenn in seiner CreateUserWizardStep
auf die Schaltfläche "Benutzer erstellen" geklickt wird. Es spielt keine Rolle, ob es zusätzliche WizardStep
s nach dem CreateUserWizardStep
gibt oder nicht.
Wenn Sie dem CreateUserWizard-Steuerelement eine benutzerdefinierte WizardStep
hinzufügen, um zusätzliche Benutzereingaben zu sammeln, kann die benutzerdefinierte WizardStep
vor oder nach dem CreateUserWizardStep
platziert 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
dem Angezeigten 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
-Objekt steht. 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 (anstelle DBNull.Value
von ) zu verwenden.
Abbildung 21: Der CreateUserWizard-Workflow, wenn ein Zusätzliches WizardStep
vorangestellt ist CreateUserWizardStep
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Wenn der benutzerdefiniert WizardStep
nachCreateUserWizardStep
dem platziert wird, erfolgt der Prozess zum Erstellen eines Benutzerkontos jedoch, bevor der Benutzer die Möglichkeit hatte, seine Heimatstadt, Homepage oder Signatur einzugeben. In diesem Fall müssen diese zusätzlichen Informationen in die Datenbank eingefügt werden, nachdem das Benutzerkonto erstellt wurde, wie Abbildung 22 veranschaulicht.
Abbildung 22: Der CreateUserWizard-Workflow, wenn ein Zusätzliches WizardStep
nach dem CreateUserWizardStep
kommt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Der in Abbildung 22 gezeigte Workflow wartet auf das Einfügen eines Datensatzes in die UserProfiles
Tabelle, bis Schritt 2 abgeschlossen ist. Wenn der Besucher jedoch nach Schritt 1 den Browser schließt, haben wir einen Zustand erreicht, in dem ein Benutzerkonto erstellt wurde, aber kein Datensatz hinzugefügt UserProfiles
wurde. Eine Problemumgehung besteht darin, einen Datensatz mit NULL
oder Standardwerten UserProfiles
im CreatedUser
Ereignishandler einzufügen (der nach Schritt 1 ausgelöst wird) und diesen Datensatz dann 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 in der Mitte beendet.
In diesem Tutorial erstellen wir eine neue WizardStep
, die nach dem CreateUserWizardStep
, aber vor dem CompleteWizardStep
auftritt. Lassen Sie uns zunächst den Assistentenschritt festlegen und konfigurieren, und dann sehen wir uns den Code an.
Wählen Sie im Smarttag des CreateUserWizard-Steuerelements die Option "Hinzufügen/Entfernen WizardStep
" aus, wodurch das WizardStep
Dialogfeld Sammlungs-Editor geöffnet wird. Fügen Sie ein neues WizardStep
hinzu, und legen Sie auf UserSettings
ID
fest, auf , auf Title
"Ihre Einstellungen" und auf StepType
Step
. Positionieren Sie sie dann so, dass sie nach dem CreateUserWizardStep
("Für Ihr neues Konto registrieren") und vor dem CompleteWizardStep
("Abschließen") kommt, wie in Abbildung 23 dargestellt.
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 Sammlungs-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 die Heimat, 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 in der Dropdownliste im Smarttag den Schritt "Ihre Einstellungen" 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 ActiveStepIndex
aktualisiert, 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 im Schritt "Ihre Einstellungen" eine Benutzeroberfläche, die drei TextBox-Steuerelemente mit den Namen HomeTown
, HomepageUrl
und Signature
enthä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, und erstellen Sie ein neues Benutzerkonto, in dem Werte für die Heimatstadt, die Homepage und die Signatur angegeben werden. Nach Abschluss des Abschlusses wird das CreateUserWizardStep
Benutzerkonto im Membership-Framework erstellt, und der CreatedUser
Ereignishandler wird ausgeführt, wodurch eine neue Zeile hinzugefügt UserProfiles
wird, jedoch mit einem Datenbankwert NULL
für HomeTown
, HomepageUrl
und Signature
. Die für Heimatort, Homepage und Signatur eingegebenen Werte werden nie verwendet. Das Nettoergebnis ist ein neues Benutzerkonto mit einem UserProfiles
Datensatz, dessen HomeTown
Felder , HomepageUrl
und Signature
noch angegeben werden müssen.
Wir müssen Code nach dem Schritt "Ihre Einstellungen" ausführen, der die vom Benutzer eingegebenen Werte für Heimat, Honepage und Signatur ü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 Ereignis von ActiveStepChanged
CreateUserWizard hinzu, und fügen Sie den folgenden Code hinzu:
protected void NewUserWizard_ActiveStepChanged(object sender, EventArgs e)
{
// Have we JUST reached the Complete step?
if (NewUserWizard.ActiveStep.Title == "Complete")
{
WizardStep UserSettings = NewUserWizard.FindControl("UserSettings") as
WizardStep;
// Programmatically reference the TextBox controls
TextBox HomeTown = UserSettings.FindControl("HomeTown") as TextBox;
TextBox HomepageUrl = UserSettings.FindControl("HomepageUrl") as TextBox;
TextBox Signature = UserSettings.FindControl("Signature") as TextBox;
// Update the UserProfiles record for this user
// Get the UserId of the just-added user
MembershipUser newUser = Membership.GetUser(NewUserWizard.UserName);
Guid newUserId = (Guid)newUser.ProviderUserKey;
// Insert a new record into UserProfiles
string connectionString =
ConfigurationManager.ConnectionStrings["SecurityTutorialsConnectionString"].ConnectionString;
string updateSql = "UPDATE UserProfiles SET HomeTown = @HomeTown, HomepageUrl
= @HomepageUrl, Signature = @Signature WHERE UserId = @UserId";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
myConnection.Open();
SqlCommand myCommand = 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();
}
}
}
Der obige Code beginnt mit der Bestimmung, ob wir gerade den Schritt "Complete" erreicht haben. Da der Schritt "Abschließen" unmittelbar nach dem Schritt "Ihre Einstellungen" erfolgt, bedeutet dies, dass der Besucher den Schritt "Ihre Einstellungen" gerade abgeschlossen hat, wenn der Besucher den Schritt "Abgeschlossen" erreicht.
In einem solchen Fall müssen wir programmgesteuert auf die TextBox-Steuerelemente in der UserSettings WizardStep
verweisen. Dies wird erreicht, indem zuerst die FindControl
-Methode verwendet wird, um programmgesteuert auf zu UserSettings WizardStep
verweisen, und dann erneut, um von innerhalb der WizardStep
auf die TextBoxes zu 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 bereitgestellten Werte für den Heimatort, die Homepage und die Signatur.
Wenn dieser Ereignishandler eingerichtet 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 zu der AdditionalUserInfo.aspx
Seite weitergeleitet werden, auf der die gerade eingegebene Heimat, Homepage und Signaturinformationen angezeigt werden.
Hinweis
Unsere Website verfügt derzeit über zwei Seiten, von denen ein Besucher ein neues Konto erstellen kann: CreatingUserAccounts.aspx
und EnhancedCreateUserWizard.aspx
. Die Sitemap und Anmeldeseite der Website verweisen auf die CreatingUserAccounts.aspx
Seite, aber die CreatingUserAccounts.aspx
Seite fordert den Benutzer nicht auf, seine Heimat, Homepage und Signaturinformationen anzugeben, und fügt keine entsprechende Zeile zu UserProfiles
hinzu. 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 sie anstelle von referenzieren EnhancedCreateUserWizard.aspx
CreatingUserAccounts.aspx
. Wenn Sie die letztere Option auswählen, müssen Sie die Membership
Datei des Ordners Web.config
aktualisieren, damit anonyme Benutzer auf die EnhancedCreateUserWizard.aspx
Seite zugreifen können.
Zusammenfassung
In diesem Tutorial haben wir uns mit Techniken zum Modellieren von Daten im Zusammenhang mit Benutzerkonten innerhalb des Mitgliedschaftsframeworks befasst. Insbesondere haben wir uns mit der Modellierung von Entitäten befasst, die eine 1:n-Beziehung mit Benutzerkonten gemeinsam nutzen, sowie daten, die eine 1:1-Beziehung gemeinsam nutzen. Darüber hinaus haben wir gesehen, wie diese zugehörigen Informationen angezeigt, eingefügt und aktualisiert werden können. Einige Beispiele verwenden das SqlDataSource-Steuerelement und andere verwenden ADO.NET Code.
In diesem Tutorial wird der Blick auf Benutzerkonten abgeschlossen. Ab dem nächsten Tutorial richten wir unsere Aufmerksamkeit auf Rollen. In den nächsten Tutorials sehen wir uns das Rollenframework an, erfahren Sie, wie Sie neue Rollen erstellen, Benutzern Rollen zuweisen, wie Sie bestimmen, zu welchen Rollen ein Benutzer gehört, und wie Sie die rollenbasierte Autorisierung anwenden.
Viel Spaß beim Programmieren!
Weitere Informationen
Weitere Informationen zu den in diesem Tutorial behandelten Themen finden Sie in den folgenden Ressourcen:
- Zugreifen auf und Aktualisieren von Daten in ASP.NET 2.0
- ASP.NET 2.0-Assistentensteuerelement
- Erstellen einer schrittweisen Benutzeroberfläche mit dem ASP.NET 2.0-Assistentensteuerelement
- Erstellen benutzerdefinierter DataSource-Steuerelementparameter
- Anpassen des CreateUserWizard-Steuerelements
- DetailsView-Steuerelement – Schnellstarts
- Anzeigen von Daten mit dem ListView-Steuerelement
- Aufteilen der Validierungssteuerelemente in ASP.NET 2.0
- Bearbeiten des Einfügens und Löschens von Daten
- Formularüberprüfung in ASP.NET
- Sammeln benutzerdefinierter Benutzerregistrierungsinformationen
- Profile in ASP.NET 2.0
- Das asp:ListView-Steuerelement
- Schnellstart für Benutzerprofile
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.