Exemplarische Vorgehensweise: Verwenden von Clientanwendungsdiensten
In diesem Thema wird das Erstellen einer Windows-Anwendung beschrieben, die Clientanwendungsdienste zum Authentifizieren von Benutzern sowie zum Abrufen von Benutzerrollen und Einstellungen verwendet.
Im Verlauf dieser exemplarischen Vorgehensweise führen Sie folgende Aufgaben aus:
Erstellen einer Windows Forms-Anwendung und Verwenden des Visual Studio-Projekt-Designers, um Clientanwendungsdienste zu aktivieren und zu konfigurieren
Erstellen einer einfachen ASP.NET-Webdienstanwendung, um die Anwendungsdienste zu hosten und die Clientkonfiguration zu testen
Hinzufügen der Formularauthentifizierung zur Anwendung. Zunächst testen Sie den Dienst mit einem hartcodierten Benutzernamen und Kennwort. Anschließend fügen Sie ein Anmeldeformular hinzu, indem Sie es als Anmeldeinformationsanbieter in der Anwendungskonfiguration angeben.
Hinzufügen rollenbasierter Funktionalität. Dabei wird eine Schaltfläche nur für Benutzer in der "Manager"-Rolle aktiviert und angezeigt.
Zugreifen auf Webeinstellungen. Zunächst laden Sie Webeinstellungen für einen authentifizierten (Test)-Benutzer auf der Seite Einstellungen des Projekt-Designers. Anschließend binden Sie mit dem Windows Forms-Designer ein Textfeld an eine Webeinstellung. Zuletzt speichern Sie den geänderten Wert auf den Server zurück.
Implementieren der Abmeldung. Sie fügen dem Formular eine Abmeldeoption hinzu und rufen eine Abmeldemethode auf.
Aktivieren des Offlinemodus. Sie stellen ein Kontrollkästchen bereit, damit Benutzer ihren Verbindungsstatus angeben können. Anschließend geben Sie über diesen Wert an, ob die Anbieter von Clientanwendungsdiensten lokal zwischengespeicherte Daten verwenden, anstatt auf ihre Webdienste zuzugreifen. Schließlich authentifizieren Sie den aktuellen Benutzer erneut, nachdem die Anwendung in den Onlinemodus zurückgekehrt ist.
Vorbereitungsmaßnahmen
Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgende Komponente:
- Visual Studio 2008.
Erstellen der Clientanwendung
Als erstes erstellen Sie ein Windows Forms-Projekt. In dieser exemplarischen Vorgehensweise wird Windows Forms verwendet, da mehr Benutzer damit vertraut sind. Bei Windows Presentation Foundation (WPF)-Projekten wird jedoch ein vergleichbares Verfahren ausgeführt.
So erstellen Sie eine Clientanwendung und aktivieren Clientanwendungsdienste
Wählen Sie in Visual Studio die Menüoption Datei | Neu | Projekt.
Erweitern Sie im Dialogfeld Neues Projekt im Bereich Projekttypen den Knoten Visual Basic oder Visual C#, und wählen Sie den Projekttyp Windows.
Stellen Sie sicher, dass .NET Framework 3.5 ausgewählt ist, und wählen Sie dann die Vorlage Windows Forms-Anwendung aus.
Ändern Sie den Projektnamen in ClientAppServicesDemo, und klicken Sie auf OK.
Ein neues Windows Forms-Projekt wird in Visual Studio geöffnet.
Wählen Sie im Menü Projekt die Option ClientAppServicesDemo-Eigenschaften aus.
Der Projekt-Designer wird angezeigt.
Wählen Sie auf der Registerkarte Dienste die Option Clientanwendungsdienste aktivieren aus.
Stellen Sie sicher, dass Formularauthentifizierung verwenden ausgewählt ist, und legen Sie Speicherort des Authentifizierungsdiensts, Speicherort des Rollendiensts und Speicherort des Webeinstellungsdiensts auf https://localhost:55555/AppServices fest.
Legen Sie für Visual Basic auf der Registerkarte Anwendung die Option Authentifizierungsmodus auf Anwendungsdefiniert fest.
Der Designer speichert die angegebenen Einstellungen in der Datei app.config der Anwendung.
Zu diesem Zeitpunkt ist die Anwendung so konfiguriert, dass vom selben Host aus auf alle drei Dienste zugegriffen wird. Im nächsten Abschnitt erstellen Sie den Host als einfache Webdienstanwendung, wodurch Sie die Clientkonfiguration testen können.
Erstellen des Anwendungsdiensthosts
In diesem Abschnitt erstellen Sie eine einfache Webdienstanwendung, die auf Benutzerdaten aus einer lokalen SQL Server Compact 3.5-Datenbankdatei zugreift. Anschließend füllen Sie die Datenbank mithilfe des ASP.NET-Websiteverwaltungs-Tool auf. Diese einfache Konfiguration ermöglicht Ihnen, die Clientanwendung schnell zu testen. Sie können aber auch den Webdiensthost so konfigurieren, dass dieser auf Benutzerdaten einer SQL Server-Datenbank oder über eine benutzerdefinierte MembershipProvider-Klasse und eine benutzerdefinierte RoleProvider-Klasse auf Benutzerdaten zugreift. Weitere Informationen finden Sie unter Erstellen und Konfigurieren der Datenbank für die Anwendungsdienste für SQL Server.
Im folgenden Verfahren erstellen und konfigurieren Sie den AppServices-Webdienst.
So erstellen und konfigurieren Sie den Anwendungsdiensthost
Wählen Sie im Projektmappen-Explorer die ClientAppServicesDemo-Projektmappe und dann im Menü Datei den Befehl Hinzufügen | Neues Projekt aus.
Erweitern Sie im Dialogfeld Neues Projekt hinzufügen im Bereich Projekttypen den Knoten Visual Basic oder Visual C#, und wählen Sie dann den Projekttyp Web.
Stellen Sie sicher, dass .NET Framework 3.5 ausgewählt ist, und wählen Sie dann die Vorlage ASP.NET-Webdienstanwendung aus.
Ändern Sie den Projektnamen in AppServices, und klicken Sie auf OK.
Der Projektmappe wird ein neues Projekt für eine ASP.NET-Webdienstanwendung hinzugefügt, und die Datei Service1.asmx.vb oder Service1.asmx.cs wird im Editor angezeigt.
Tipp
Die Datei Service1.asmx.vb oder Service1.asmx.cs wird in diesem Beispiel nicht verwendet. Wenn die Arbeitsumgebung übersichtlich bleiben soll, können Sie sie schließen und aus dem Projektmappen-Explorer löschen.
Wählen Sie im Projektmappen-Explorer das Projekt AppServices und dann im Menü Projekt die Option AppServices-Eigenschaften aus.
Der Projekt-Designer wird angezeigt.
Stellen Sie auf der Registerkarte Web sicher, dass Visual Studio Development Server verwenden ausgewählt ist.
Wählen Sie Bestimmter Anschluss aus, geben Sie den Wert 55555 ein, und legen Sie dann Virtueller Pfad auf /AppServices fest.
Speichern Sie alle Dateien.
Öffnen Sie im Projektmappen-Explorer die Datei Web.config, und suchen Sie das <system.web>-Starttag.
Fügen Sie vor dem <system.web>-Tag das folgende Markup hinzu.
Durch die Elemente authenticationService, profileService und roleService in diesem Markup werden die Anwendungsdienste aktiviert und konfiguriert. Zu Testzwecken wird das requireSSL-Attribut des authenticationService-Elements auf "false" festgelegt. Das readAccessProperties-Attribut und writeAccessProperties-Attribut des profileService-Elements geben an, dass die WebSettingsTestText-Eigenschaft Lese-/Schreibzugriffe unterstützt.
Tipp
In Produktionscode sollten Sie immer über die Secure Sockets Layer (SSL, unter Verwendung des HTTPS-Protokolls) auf den Authentifizierungsdienst zugreifen. Informationen zum Verwenden von SSL finden Sie unter Configuring Secure Sockets Layer (IIS 6.0 Operations Guide).
<system.web.extensions> <scripting> <webServices> <authenticationService enabled="true" requireSSL = "false"/> <profileService enabled="true" readAccessProperties="WebSettingsTestText" writeAccessProperties="WebSettingsTestText" /> <roleService enabled="true"/> </webServices> </scripting> </system.web.extensions>
Fügen Sie nach dem <system.web>-Starttag das folgende Markup hinzu, sodass es sich innerhalb des <system.web>-Elements befindet.
Durch das profile-Element wird eine einzelne Webeinstellung mit dem Namen WebSettingsTestText konfiguriert.
<profile enabled="true" > <properties> <add name="WebSettingsTestText" type="string" readOnly="false" defaultValue="DefaultText" serializeAs="String" allowAnonymous="false" /> </properties> </profile>
Im folgenden Verfahren verwenden Sie das ASP.NET-Websiteverwaltungs-Tool, um die Dienstkonfiguration abzuschließen und die lokale Datenbankdatei aufzufüllen. Sie fügen zwei Benutzer mit dem Namen employee und manager hinzu, die zu zwei Rollen mit jeweils dem gleichen Namen gehören. Die Benutzerkennwörter lauten manager! und employee!.
So konfigurieren Sie Mitgliedschaft und Rollen
Wählen Sie im Projektmappen-Explorer das Projekt AppServices und dann im Menü Projekt die Option ASP.NET-Konfiguration aus.
Das ASP.NET-Websiteverwaltungs-Tool wird angezeigt.
Klicken Sie auf der Registerkarte Sicherheit auf Verwenden Sie den Setup-Assistenten für die Sicherheit, um die Sicherheit Schritt für Schritt zu konfigurieren.
Der Setup-Assistent für die Sicherheit wird mit der Seite Willkommen angezeigt.
Klicken Sie auf Next.
Der Schritt Zugriffsmethode auswählen wird angezeigt.
Wählen Sie Aus dem Internet aus. Damit wird der Dienst so konfiguriert, dass er die Forms-Authentifizierung statt der Windows-Authentifizierung verwendet.
Klicken Sie zweimal auf Weiter.
Der Schritt Rollen definieren wird angezeigt.
Wählen Sie Rollen für diese Website aktivieren aus.
Klicken Sie auf Next. Das Formular Neue Rolle erstellen wird angezeigt.
Geben Sie im Textfeld Neuer Rollenname den Text manager ein, und klicken Sie dann auf Rolle hinzufügen.
Die Tabelle Vorhandene Rollen wird mit dem angegebenen Wert angezeigt.
Ersetzen Sie im Textfeld Neuer Rollenname den Eintrag manager durch employee, und klicken Sie dann auf Rolle hinzufügen.
Der neue Wert wird in der Tabelle Vorhandene Rollen angezeigt.
Klicken Sie auf Next.
Der Schritt Neue Benutzer hinzufügen wird angezeigt.
Geben Sie im Formular Benutzer erstellen die folgenden Werte an.
Benutzername
manager
Kennwort
manager!
Kennwort bestätigen
manager!
E-Mail
manager@contoso.com
Sicherheitsfrage
manager
Sicherheitsantwort
manager
Klicken Sie auf Benutzer erstellen.
Eine Erfolgsmeldung wird angezeigt.
Tipp
Die Werte für E-Mail, Sicherheitsfrage und Sicherheitsantwort sind für das Formular obligatorisch, werden in diesem Beispiel jedoch nicht verwendet.
Klicken Sie auf Weiter.
Das Formular Benutzer erstellen wird erneut angezeigt.
Geben Sie im Formular Benutzer erstellen die folgenden Werte an.
Benutzername
employee
Kennwort
employee!
Kennwort bestätigen
employee!
E-Mail
employee@contoso.com
Sicherheitsfrage
Employee
Sicherheitsantwort
employee
Klicken Sie auf Benutzer erstellen.
Eine Erfolgsmeldung wird angezeigt.
Klicken Sie auf Fertig stellen.
Das Websiteverwaltungs-Tool wird erneut angezeigt.
Klicken Sie auf Manager-Benutzer.
Die Liste der Benutzer wird angezeigt.
Klicken Sie auf Rollen bearbeiten für den Benutzer employee, und wählen Sie dann die Rolle employee aus.
Klicken Sie auf Rollen bearbeiten für den Benutzer manager, und wählen Sie dann die Rolle manager aus.
Schließen Sie das Browserfenster, in dem sich das Websiteverwaltungs-Tool befindet.
Wenn Sie in einem Meldungsfeld gefragt werden, ob Sie die geänderte Datei Web.config erneut laden möchten, klicken Sie auf Ja.
Damit ist die Einrichtung des Webdiensts abgeschlossen. Sie können jetzt F5 drücken, um die Clientanwendung auszuführen. Der ASP.NET Development Server wird zusammen mit der Clientanwendung automatisch gestartet. Der Server wird nach dem Beenden der Anwendung zwar weiterhin ausgeführt, aber beim Neustart der Anwendung ebenfalls neu gestartet. Dadurch können alle an der Datei Web.config vorgenommenen Änderungen ermittelt werden.
Um den Server manuell anzuhalten, klicken Sie mit der rechten Maustaste im Infobereich der Taskleiste auf das Symbol für den ASP.NET Development Server, und klicken Sie dann auf Beenden. Dies ist manchmal hilfreich, um einen sauberen Neustart sicherzustellen.
Hinzufügen der Formularauthentifizierung
Im folgenden Verfahren fügen Sie dem Hauptformular Code hinzu, durch den versucht wird, den Benutzer zu überprüfen und im Fall ungültiger Anmeldeinformationen der Zugriff verweigert wird. Mit einem hartcodierten Benutzernamen und Kennwort wird der Dienst getestet.
So überprüfen Sie den Benutzer im Anwendungscode
Fügen Sie im Projektmappen-Explorer im Projekt ClientAppServicesDemo einen Verweis auf die Assembly System.Web hinzu.
Wählen Sie die Datei Form1 und dann Ansicht | Code aus dem Visual Studio-Hauptmenü aus.
Fügen Sie im Code-Editor folgende Anweisungen am Anfang der Datei Form1 hinzu.
Imports System.Net Imports System.Threading Imports System.Web.ClientServices Imports System.Web.ClientServices.Providers Imports System.Web.Security
using System.Net; using System.Threading; using System.Web.ClientServices; using System.Web.ClientServices.Providers; using System.Web.Security;
Doppelklicken Sie im Projektmappen-Explorer auf Form1, um den Designer anzuzeigen.
Doppelklicken Sie im Designer auf die Formularoberfläche, um einen Form.Load-Ereignishandler mit dem Namen Form1_Load zu erstellen.
Der Code-Editor wird angezeigt, wobei sich der Cursor innerhalb der Form1_Load-Methode befindet.
Fügen Sie der Form1_Load-Methode folgenden Code hinzu:
Durch diesen Code wird der Zugriff auf nicht authentifizierte Benutzer verweigert, indem die Anwendung beendet wird. Alternativ könnten Sie nicht authentifizierten Benutzern zwar Zugriff auf das Formular gewähren, aber den Zugriff auf bestimmte Funktionen verweigern. Im Normfall würden Sie den Benutzernamen und das Kennwort nicht in dieser Form hart codieren, für Testzwecke ist dies jedoch hilfreich. Im nächsten Abschnitt ersetzen Sie diesen Code durch weniger störanfälligen Code, durch den ein Anmeldedialogfeld angezeigt und die Ausnahmebehandlung eingeschlossen wird.
Beachten Sie, dass sich die static Membership.ValidateUser-Methode in .NET Framework, Version 2.0 befindet. Diese Methode delegiert die Arbeit an den konfigurierten Authentifizierungsanbieter und gibt true zurück, wenn die Authentifizierung erfolgreich ist. Die Anwendung erfordert keinen direkten Verweis auf den Clientauthentifizierungsanbieter.
If Not Membership.ValidateUser("manager", "manager!") Then MessageBox.Show("Unable to authenticate.", "Not logged in", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Application.Exit() End If
if (!Membership.ValidateUser("manager", "manager!")) { MessageBox.Show("Unable to authenticate.", "Not logged in", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); }
Sie können jetzt F5 drücken, um die Anwendung auszuführen. Da Sie den richtigen Benutzernamen und das richtige Kennwort angeben, wird das Formular angezeigt.
Tipp
Wenn Sie die Anwendung nicht ausführen können, versuchen Sie, den ASP.NET Development Server anzuhalten. Wenn der Server neu gestartet wird, überprüfen Sie, ob der Anschluss auf 55555 festgelegt ist.
Um stattdessen die Fehlermeldung zu sehen, ändern Sie die ValidateUser-Parameter. Beispielsweise ersetzen Sie den zweiten "manager!"-Parameter durch ein falsches Kennwort wie "MANAGER".
Hinzufügen eines Anmeldeformulars als Anmeldeinformationsanbieter
Sie können die Benutzeranmeldeinformationen im Anwendungscode abrufen und an die ValidateUser-Methode übergeben. Häufig ist es jedoch hilfreich, Code zum Abrufen der Anmeldeinformationen vom Anwendungscode zu trennen, falls dieser später geändert werden soll.
Im folgenden Verfahren konfigurieren Sie die Anwendung für die Verwendung eines Anmeldeinformationsanbieters und ändern dann den ValidateUser-Methodenaufruf, um Empty für beide Parameter zu übergeben. Die leeren Zeichenfolgen signalisieren der ValidateUser-Methode, die GetCredentials-Methode des konfigurierten Anmeldeinformationsanbieters aufzurufen.
So konfigurieren Sie die Anwendung für die Verwendung eines Anmeldeinformationsanbieters
Wählen Sie im Projektmappen-Explorer das Projekt ClientAppServicesDemo und dann im Menü Projekt die Option ClientAppServicesDemo-Eigenschaften.
Der Projekt-Designer wird angezeigt.
Legen Sie auf der Registerkarte Dienste die Option Optional: Anmeldeinformationsanbieter auf folgenden Wert fest. Dieser Wert gibt den durch die Assembly qualifizierten Typnamen an.
ClientAppServicesDemo.Login, ClientAppServicesDemo
Ersetzen Sie in der Codedatei Form1 den Code in der Form1_Load-Methode durch folgenden Code.
Durch diesen Code wird eine Begrüßungsnachricht angezeigt und dann die ValidateUsingCredentialsProvider-Methode aufgerufen, die im nächsten Schritt hinzugefügt wird. Wenn der Benutzer nicht authentifiziert wird, gibt die ValidateUsingCredentialsProvider-Methode den Wert false zurück, und die Form1_Load-Methode wird zurückgegeben. Dadurch wird verhindert, dass vor dem Beenden der Anwendung zusätzlicher Code ausgeführt wird. Die Begrüßungsnachricht ist nützlich, um den Neustart der Anwendung deutlich zu machen. Wenn Sie später in dieser exemplarischen Vorgehensweise die Abmeldung implementieren, fügen Sie Code zum Neustarten der Anwendung hinzu.
MessageBox.Show("Welcome to the Client Application Services Demo.", _ "Welcome!") If Not ValidateUsingCredentialsProvider() Then Return
MessageBox.Show("Welcome to the Client Application Services Demo.", "Welcome!"); if (!ValidateUsingCredentialsProvider()) return;
Fügen Sie die folgende Methode nach der Form1_Load-Methode hinzu.
Diese Methode übergibt leere Zeichenfolgen an die staticMembership.ValidateUser-Methode, wodurch das Anmeldedialogfeld angezeigt wird. Wenn der Authentifizierungsdienst nicht verfügbar ist, löst die ValidateUser-Methode eine WebException aus. In diesem Fall zeigt die ValidateUsingCredentialsProvider-Methode eine Warnmeldung an, in der der Benutzer gefragt wird, ob er den Vorgang im Offlinemodus wiederholen möchte. Für diese Funktionalität ist das in Gewusst wie: Konfigurieren von Clientanwendungsdiensten beschriebene Feature Kennworthash lokal speichern, um Offlineanmeldung zu ermöglichen erforderlich. Dieses Feature wird standardmäßig für neue Projekte aktiviert.
Wenn der Benutzer nicht überprüft wird, zeigt die ValidateUsingCredentialsProvider-Methode eine Fehlermeldung an und beendet die Anwendung. Schließlich gibt diese Methode das Ergebnis des Authentifizierungsversuchs zurück.
Private Function ValidateUsingCredentialsProvider() As Boolean Dim isAuthorized As Boolean = False Try ' Call ValidateUser with empty strings in order to display the ' login dialog box configured as a credentials provider. isAuthorized = Membership.ValidateUser( _ String.Empty, String.Empty) Catch ex As System.Net.WebException If DialogResult.OK = MessageBox.Show( _ "Unable to access the authentication service." & _ Environment.NewLine & "Attempt login in offline mode?", _ "Warning", MessageBoxButtons.OKCancel, _ MessageBoxIcon.Warning) Then ConnectivityStatus.IsOffline = True isAuthorized = Membership.ValidateUser( _ String.Empty, String.Empty) End If End Try If Not isAuthorized Then MessageBox.Show("Unable to authenticate.", "Not logged in", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Application.Exit() End If Return isAuthorized End Function
private bool ValidateUsingCredentialsProvider() { bool isAuthorized = false; try { // Call ValidateUser with empty strings in order to display the // login dialog box configured as a credentials provider. isAuthorized = Membership.ValidateUser( String.Empty, String.Empty); } catch (System.Net.WebException) { if (DialogResult.OK == MessageBox.Show( "Unable to access the authentication service." + Environment.NewLine + "Attempt login in offline mode?", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)) { ConnectivityStatus.IsOffline = true; isAuthorized = Membership.ValidateUser( String.Empty, String.Empty); } } if (!isAuthorized) { MessageBox.Show("Unable to authenticate.", "Not logged in", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } return isAuthorized; }
Erstellen eines Anmeldeformulars
Ein Anmeldeinformationsanbieter ist eine Klasse, durch die die IClientFormsAuthenticationCredentialsProvider-Schnittstelle implementiert wird. Diese Schnittstelle verfügt über eine einzelne Methode mit dem Namen GetCredentials, durch die ein ClientFormsAuthenticationCredentials-Objekt zurückgegeben wird. In den folgenden Verfahren wird die Erstellung eines Anmeldedialogfelds beschrieben, durch das GetCredentials für die Anzeige des Dialogfelds und die Rückgabe benutzerdefinierter Anmeldeinformationen implementiert wird.
Für Visual Basic und C# werden separate Verfahren bereitgestellt, da Visual Basic die Vorlage Anmeldeformular zur Verfügung stellt. Dies spart Zeit und Programmieraufwand.
So erstellen Sie ein Anmeldedialogfeld als Anmeldeinformationsanbieter in Visual Basic
Wählen Sie im Projektmappen-Explorer das Projekt ClientAppServicesDemo aus und dann im Menü Projekt den Befehl Neues Element hinzufügen aus.
Wählen Sie im Dialogfeld Neues Element hinzufügen die Vorlage Anmeldeformular aus, ändern Sie das Element Name in Login.vb, und klicken Sie auf Hinzufügen.
Das Anmeldedialogfeld wird im Windows Forms-Designer geöffnet.
Wählen Sie im Designer die Schaltfläche OK aus, und legen Sie im Eigenschaftenfenster die Eigenschaft DialogResult auf OK fest.
Fügen Sie im Designer ein CheckBox-Steuerelement unterhalb des Textfelds Kennwort hinzu.
Geben Sie im Eigenschaftenfenster den (Name)-Wert rememberMeCheckBox und den Text-Wert &Remember me an.
Wählen Sie Ansicht | Code aus dem Visual Studio-Hauptmenü.
Fügen Sie im Code-Editor folgenden Code am Anfang der Datei hinzu.
Imports System.Web.ClientServices.Providers
Ändern Sie die Klassensignatur, sodass die Klasse die IClientFormsAuthenticationCredentialsProvider-Schnittstelle implementiert.
Public Class Login Implements IClientFormsAuthenticationCredentialsProvider
Stellen Sie sicher, dass der Cursor nach IClientformsAuthenticationCredentialsProvider positioniert ist, und drücken Sie die EINGABETASTE, um die GetCredentials-Methode zu generieren.
Suchen Sie die GetCredentials-Implementierung, und ersetzen Sie sie durch den folgenden Code.
Public Function GetCredentials() As _ ClientFormsAuthenticationCredentials Implements _ IClientFormsAuthenticationCredentialsProvider.GetCredentials If Me.ShowDialog() = DialogResult.OK Then Return New ClientFormsAuthenticationCredentials( _ UsernameTextBox.Text, PasswordTextBox.Text, _ rememberMeCheckBox.Checked) Else Return Nothing End If End Function
Durch die folgende C#-Prozedur wird die gesamte Codeauflistung für ein einfaches Anmeldedialogfeld bereitgestellt. Das Layout dieses Dialogfelds ist etwas einfach gehalten, da es hauptsächlich um die GetCredentials-Implementierung geht.
So erstellen Sie ein Anmeldedialogfeld als Anmeldeinformationsanbieter in C#
Wählen Sie im Projektmappen-Explorer das Projekt ClientAppServicesDemo und dann im Menü Projekt die Option Klasse hinzufügen aus.
Ändern Sie im Dialogfeld Neues Element hinzufügen den Name-Wert in Login.cs, und klicken Sie auf Hinzufügen.
Die Datei Login.cs wird im Code-Editor geöffnet.
Ersetzen Sie den Standardcode durch folgenden Code.
using System.Windows.Forms; using System.Web.ClientServices.Providers; namespace ClientAppServicesDemo { class Login : Form, IClientFormsAuthenticationCredentialsProvider { private TextBox usernameTextBox; private TextBox passwordTextBox; private CheckBox rememberMeCheckBox; private Button OK; private Button cancel; private Label label1; private Label label2; public ClientFormsAuthenticationCredentials GetCredentials() { if (this.ShowDialog() == DialogResult.OK) { return new ClientFormsAuthenticationCredentials( usernameTextBox.Text, passwordTextBox.Text, rememberMeCheckBox.Checked); } else { return null; } } public Login() { InitializeComponent(); } private void CloseForm(object sender, System.EventArgs e) { this.Close(); } private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.usernameTextBox = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.passwordTextBox = new System.Windows.Forms.TextBox(); this.rememberMeCheckBox = new System.Windows.Forms.CheckBox(); this.OK = new System.Windows.Forms.Button(); this.cancel = new System.Windows.Forms.Button(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(13, 13); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(58, 13); this.label1.TabIndex = 0; this.label1.Text = "&User name"; // // usernameTextBox // this.usernameTextBox.Location = new System.Drawing.Point(13, 30); this.usernameTextBox.Name = "usernameTextBox"; this.usernameTextBox.Size = new System.Drawing.Size(157, 20); this.usernameTextBox.TabIndex = 1; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(13, 57); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(53, 13); this.label2.TabIndex = 2; this.label2.Text = "&Password"; // // passwordTextBox // this.passwordTextBox.Location = new System.Drawing.Point(13, 74); this.passwordTextBox.Name = "passwordTextBox"; this.passwordTextBox.PasswordChar = '*'; this.passwordTextBox.Size = new System.Drawing.Size(157, 20); this.passwordTextBox.TabIndex = 3; // // rememberMeCheckBox // this.rememberMeCheckBox.AutoSize = true; this.rememberMeCheckBox.Location = new System.Drawing.Point(13, 101); this.rememberMeCheckBox.Name = "rememberMeCheckBox"; this.rememberMeCheckBox.Size = new System.Drawing.Size(94, 17); this.rememberMeCheckBox.TabIndex = 4; this.rememberMeCheckBox.Text = "&Remember me"; this.rememberMeCheckBox.UseVisualStyleBackColor = true; // // OK // this.OK.DialogResult = System.Windows.Forms.DialogResult.OK; this.OK.Location = new System.Drawing.Point(13, 125); this.OK.Name = "OK"; this.OK.Size = new System.Drawing.Size(75, 23); this.OK.TabIndex = 5; this.OK.Text = "&OK"; this.OK.UseVisualStyleBackColor = true; // // cancel // this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancel.Location = new System.Drawing.Point(95, 125); this.cancel.Name = "cancel"; this.cancel.Size = new System.Drawing.Size(75, 23); this.cancel.TabIndex = 6; this.cancel.Text = "&Cancel"; this.cancel.UseVisualStyleBackColor = true; // // Login // this.AcceptButton = this.OK; this.CancelButton = this.cancel; this.ClientSize = new System.Drawing.Size(187, 168); this.Controls.Add(this.cancel); this.Controls.Add(this.OK); this.Controls.Add(this.rememberMeCheckBox); this.Controls.Add(this.passwordTextBox); this.Controls.Add(this.label2); this.Controls.Add(this.usernameTextBox); this.Controls.Add(this.label1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "Login"; this.Text = "Login"; this.ResumeLayout(false); this.PerformLayout(); } } }
Wenn Sie die Anwendung jetzt ausführen, sehen sie das Anmeldedialogfeld. Um diesen Code zu testen, probieren verschiedene Anmeldeinformationen – sowohl gültige als auch ungültige – aus, um sicherzustellen, dass Sie nur mit gültigen Anmeldeinformationen auf das Formular zugreifen können. Gültige Benutzernamen sind employee sowie manager, und die Kennwörter lauten employee! und manager!.
Tipp
Wählen Sie an dieser Stelle nicht Remember me aus, da Sie sich ansonsten erst unter einem anderen Benutzernamen anmelden können, nachdem Sie später in dieser exemplarischen Vorgehensweise die Abmeldung implementiert haben.
Hinzufügen rollenbasierter Funktionalität
Im folgenden Verfahren fügen Sie dem Formular eine Schaltfläche hinzu, die nur Benutzern mit der Manager-Rolle angezeigt wird.
So ändern Sie die Benutzeroberfläche auf Grundlage der Benutzerrolle
Wählen Sie im Projektmappen-Explorer im Projekt ClientAppServicesDemo den Eintrag Form1 und dann Ansicht | Designer aus dem Visual Studio-Hauptmenü.
Fügen Sie dem Formular im Designer ein Button-Steuerelement aus der ToolBox hinzu.
Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften für die Schaltfläche fest.
Eigenschaft
Wert
(Name)
managerOnlyButton
Text
&Manager-Aufgabe
Visible
False
Fügen Sie im Code-Editor für Form1 folgenden Code am Ende der Form1_Load-Methode hinzu.
Durch diesen Code wird die DisplayButtonForManagerRole-Methode aufgerufen, die im nächsten Schritt hinzugefügt wird.
DisplayButtonForManagerRole()
DisplayButtonForManagerRole();
Fügen Sie am Ende der Form1-Klasse die folgende Methode hinzu.
Durch diese Methode wird die IsInRole-Methode von IPrincipal aufgerufen, der von der static Thread.CurrentPrincipal-Eigenschaft zurückgegeben wird. Für Anwendungen, die für die Verwendung von Clientanwendungsdiensten konfiguriert sind, gibt diese Eigenschaft ClientRolePrincipal zurück. Da diese Klasse die IPrincipal-Schnittstelle implementiert, müssen Sie nicht explizit darauf verweisen.
Wenn der Benutzer über die "Manager"-Rolle verfügt, legt die DisplayButtonForManagerRole-Methode die Visible-Eigenschaft von managerOnlyButton auf true fest. Durch diese Methode wird außerdem eine Fehlermeldung angezeigt, wenn eine WebException ausgelöst wird, die darauf hinweist, dass der Rollendienst nicht verfügbar ist.
Tipp
Die IsInRole-Methode gibt immer false zurück, wenn die Benutzeranmeldung abgelaufen ist. Dies ist nicht der Fall, wenn die Anwendung die IsInRole-Methode kurz nach der Authentifizierung einmal aufruft, wie im Beispielcode für diese exemplarische Vorgehensweise veranschaulicht. Wenn Ihre Anwendung Benutzerrollen zu anderen Zeiten abrufen muss, können Sie Code hinzufügen, durch den Benutzer, deren Anmeldung abgelaufen ist, erneut überprüft werden. Wenn alle gültigen Benutzern Rollen zugewiesen sind, können Sie durch Aufrufen der ClientRoleProvider.GetRolesForUser-Methode feststellen, ob die Anmeldung abgelaufen ist. Wenn keine Rollen zurückgegeben werden, ist die Anmeldung abgelaufen. Ein Beispiel für diese Funktion finden Sie unter den Ausführungen zur GetRolesForUser-Methode. Diese Funktionalität ist nur erforderlich, wenn Sie in der Anwendungskonfiguration Erneute Benutzeranmeldung bei Ablauf des Cookies anfordern ausgewählt haben. Weitere Informationen finden Sie unter Gewusst wie: Konfigurieren von Clientanwendungsdiensten.
Private Sub DisplayButtonForManagerRole() Try If Thread.CurrentPrincipal.IsInRole("manager") Then managerOnlyButton.Visible = True End If Catch ex As System.Net.WebException MessageBox.Show("Unable to access the roles service.", _ "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning) End Try End Sub
private void DisplayButtonForManagerRole() { try { if (Thread.CurrentPrincipal.IsInRole("manager")) { managerOnlyButton.Visible = true; } } catch (System.Net.WebException) { MessageBox.Show("Unable to access the role service.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
Wenn die Authentifizierung erfolgreich ist, legt der Clientauthentifizierungsanbieter die Thread.CurrentPrincipal-Eigenschaft auf eine Instanz der ClientRolePrincipal-Klasse fest. Diese Klasse implementiert die IsInRole-Methode, sodass die Arbeit an den konfigurierten Rollenanbieter delegiert wird. Wie oben benötigt der Anwendungscode keinen direkten Verweis auf den Dienstanbieter.
Sie können die Anwendung jetzt ausführen und sich als employee anmelden, wobei die Schaltfläche nicht angezeigt wird. Melden Sie sich dann als manager an, damit die Schaltfläche eingeblendet wird.
Zugriff auf Webeinstellungen
Im folgenden Verfahren fügen Sie dem Formular ein Textfeld hinzu und binden es an eine Webeinstellung. Wie im vorangehenden Code, in dem Authentifizierung und Rollen verwendet werden, greift der Einstellungscode nicht direkt auf den Einstellungsanbieter zu. Stattdessen verwendet er die Settings-Klasse mit starker Typisierung (auf die in C# als Properties.Settings.Default und in Visual Basic als My.Settings zugegriffen wird). Diese wird von Visual Studio für das Projekt generiert.
So verwenden Sie Webeinstellungen in der Benutzeroberfläche
Stellen Sie sicher, dass der ASP.NET Web Development Server immer noch ausgeführt wird, indem Sie den Ínfobereich der Taskleiste überprüfen. Falls Sie den Server angehalten haben, starten Sie die Anwendung neu (wodurch der Server automatisch gestartet wird) und schließen dann das Anmeldedialogfeld.
Wählen Sie im Projektmappen-Explorer das Projekt ClientAppServicesDemo und dann im Menü Projekt die Option ClientAppServicesDemo-Eigenschaften.
Der Projekt-Designer wird angezeigt.
Klicken Sie auf der Registerkarte Einstellungen auf Webeinstellungen laden.
Ein Dialogfeld Anmelden wird angezeigt.
Geben Sie Anmeldeinformationen für employee oder manager ein, und klicken Sie auf Anmelden. Die verwendete Webeinstellung ist so konfiguriert, dass nur authentifizierte Anwendender darauf zugreifen dürfen. Es werden also keine Einstellungen geladen, wenn Sie auf Anmeldung überspringen klicken.
Die Einstellung WebSettingsTestText wird im Designer mit dem Standardwert DefaultText angezeigt. Darüber hinaus wird eine Settings-Klasse, die eine WebSettingsTestText-Eigenschaft enthält, für das Projekt generiert.
Wählen Sie im Projektmappen-Explorer im Projekt ClientAppServicesDemo den Eintrag Form1 und dann Ansicht | Designer aus dem Visual Studio-Hauptmenü.
Fügen Sie dem Formular im Designer ein TextBox-Steuerelement hinzu.
Geben Sie im Eigenschaftenfenster den (Name)-Wert webSettingsTestTextBox an.
Fügen Sie im Code-Editor den folgenden Code am Ende der Form1_Load-Methode hinzu.
Durch diesen Code wird die BindWebSettingsTestTextBox-Methode aufgerufen, die im nächsten Schritt hinzugefügt wird.
BindWebSettingsTestTextBox()
BindWebSettingsTestTextBox();
Fügen Sie am Ende der Form1-Klasse die folgende Methode hinzu.
Durch diese Methode wird die Text-Eigenschaft von webSettingsTestTextBox an die WebSettingsTestText-Eigenschaft der Settings-Klasse gebunden, die oben in diesem Verfahren generiert wurde. Durch diese Methode wird außerdem eine Fehlermeldung angezeigt, wenn eine WebException ausgelöst wird, die darauf hinweist, dass der Webeinstellungsdienst nicht verfügbar ist.
Private Sub BindWebSettingsTestTextBox() Try Me.webSettingsTestTextBox.DataBindings.Add("Text", _ My.Settings, "WebSettingsTestText") Catch ex As WebException MessageBox.Show("Unable to access the Web settings service.", _ "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning) End Try End Sub
private void BindWebSettingsTestTextBox() { try { this.webSettingsTestTextBox.DataBindings.Add("Text", Properties.Settings.Default, "WebSettingsTestText"); } catch (WebException) { MessageBox.Show("Unable to access the Web settings service.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
Tipp
Sie verwenden die Datenbindung normalerweise, um die automatische bidirektionale Kommunikation zwischen einem Steuerelement und einer Webeinstellung zu aktivieren. Sie können jedoch auch direkt auf Webeinstellungen zugreifen, wie im folgenden Beispiel dargestellt:
webSettingsTestTextBox.Text = My.Settings.WebSettingsTestText
webSettingsTestTextBox.Text = Properties.Settings.Default.WebSettingsTestText;
Wählen Sie im Designer das Formular aus, und klicken Sie dann im Eigenschaftenfenster auf die Schaltfläche Ereignisse.
Wählen Sie das FormClosing-Ereignis aus, und drücken Sie die EINGABETASTE, um einen Ereignishandler zu generieren.
Ersetzen Sie die generierte Methode durch folgenden Code.
Der FormClosing-Ereignishandler ruft die SaveSettings-Methode auf, die auch von der Abmeldefunktion verwendet wird, die Sie im nächsten Abschnitt hinzufügen. Durch die SaveSettings-Methode wird zunächst bestätigt, dass der Benutzer sich nicht abgemeldet hat. Zu diesem Zweck wird die AuthenticationType-Eigenschaft von IIdentity überprüft, die vom aktuellen Prinzipal zurückgegeben wird. Der aktuelle Prinzipal wird über die static CurrentPrincipal-Eigenschaft abgerufen. Wenn der Benutzer für Clientanwendungsdienste authentifiziert wurde, lautet der Authentifizierungstyp "ClientForms". Es reicht nicht aus, dass die SaveSettings-Methode die IIdentity.IsAuthenticated-Eigenschaft überprüft, da der Benutzer nach der Abmeldung über eine gültige Windows-Identität verfügen könnte.
Wenn sich der Benutzer nicht abgemeldet hat, ruft die SaveSettings-Methode die Save-Methode der oben in diesem Verfahren generierten Settings-Klasse auf. Diese Methode kann eine WebException auslösen, wenn das Authentifizierungscookie abgelaufen ist. Dies ist nur der Fall, wenn Sie in der Anwendungskonfiguration Erneute Benutzeranmeldung bei Ablauf des Cookies anfordern ausgewählt haben. Weitere Informationen finden Sie unter Gewusst wie: Konfigurieren von Clientanwendungsdiensten. Die SaveSettings-Methode behandelt das Ablaufzeitintervall von Cookies, indem ValidateUser aufgerufen wird, um das Anmeldedialogfeld anzuzeigen. Wenn sich der Benutzer erfolgreich anmeldet, versucht die SaveSettings-Methode, die Einstellungen zu speichern, indem sie sich selbst erneut aufruft.
Wie im vorherigen Code zeigt die SaveSettings-Methode eine Fehlermeldung an, wenn der Remotedienst nicht verfügbar ist. Wenn der Einstellungsanbieter nicht auf den Remotedienst zugreifen kann, werden die Einstellungen trotzdem im lokalen Cache gespeichert und beim Neustart der Anwendung erneut geladen.
Private Sub Form1_FormClosing(ByVal sender As Object, _ ByVal e As FormClosingEventArgs) Handles Me.FormClosing SaveSettings() End Sub Private Sub SaveSettings() ' Return without saving if the authentication type is not ' "ClientForms". This indicates that the user is logged out. If Not Thread.CurrentPrincipal.Identity.AuthenticationType _ .Equals("ClientForms") Then Return Try My.Settings.Save() Catch ex As WebException If ex.Message.Contains("You must log on to call this method.") Then MessageBox.Show( _ "Your login has expired. Please log in again to save " & _ "your settings.", "Attempting to save settings...") Dim isAuthorized As Boolean = False Try ' Call ValidateUser with empty strings in order to ' display the login dialog box configured as a ' credentials provider. If Not Membership.ValidateUser( _ String.Empty, String.Empty) Then MessageBox.Show("Unable to authenticate. " & _ "Settings were not saved on the remote service.", _ "Not logged in", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Else ' Try again. SaveSettings() End If Catch ex2 As System.Net.WebException MessageBox.Show( _ "Unable to access the authentication service. " & _ "Settings were not saved on the remote service.", _ "Not logged in", MessageBoxButtons.OK, _ MessageBoxIcon.Warning) End Try Else MessageBox.Show("Unable to access the Web settings service. " & _ "Settings were not saved on the remote service.", _ "Not logged in", MessageBoxButtons.OK, _ MessageBoxIcon.Warning) End If End Try End Sub
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { SaveSettings(); } private void SaveSettings() { // Return without saving if the authentication type is not // "ClientForms". This indicates that the user is logged out. if (!Thread.CurrentPrincipal.Identity.AuthenticationType .Equals("ClientForms")) return; try { Properties.Settings.Default.Save(); } catch (WebException ex) { if (ex.Message.Contains("You must log on to call this method.")) { MessageBox.Show( "Your login has expired. Please log in again to save " + "your settings.", "Attempting to save settings..."); try { // Call ValidateUser with empty strings in order to // display the login dialog box configured as a // credentials provider. if (!Membership.ValidateUser(String.Empty, String.Empty)) { MessageBox.Show("Unable to authenticate. " + "Settings were not saved on the remote service.", "Not logged in", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { // Try again. SaveSettings(); } } catch (System.Net.WebException) { MessageBox.Show( "Unable to access the authentication service. " + "Settings were not saved on the remote service.", "Not logged in", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } else { MessageBox.Show("Unable to access the Web settings service. " + "Settings were not saved on the remote service.", "Not logged in", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } }
Fügen Sie am Ende der Form1-Klasse die folgende Methode hinzu.
Dieser Code behandelt das ClientSettingsProvider.SettingsSaved-Ereignis und zeigt eine Warnung an, wenn eine der Einstellungen nicht gespeichert werden konnte. Das SettingsSaved-Ereignis tritt nicht auf, wenn der Einstellungsdienst nicht verfügbar oder das Authentifizierungscookie abgelaufen ist. Das SettingsSaved-Ereignis tritt beispielsweise auf, wenn sich der Benutzer bereits abgemeldet hat. Sie können diesen Ereignishandler testen, indem Sie der SaveSettings-Methode unmittelbar vor dem Save-Methodenaufruf Abmeldecode hinzufügen. Der verwendbare Abmeldecode wird im nächsten Abschnitt beschrieben.
Private WithEvents settingsProvider As ClientSettingsProvider = My.Settings _ .Providers("System.Web.ClientServices.Providers.ClientSettingsProvider") Private Sub Form1_SettingsSaved(ByVal sender As Object, _ ByVal e As SettingsSavedEventArgs) _ Handles settingsProvider.SettingsSaved ' If any settings were not saved, display a list of them. If e.FailedSettingsList.Count > 0 Then Dim failedSettings As String = String.Join( _ Environment.NewLine, e.FailedSettingsList.ToArray()) Dim message As String = String.Format("{0}{1}{1}{2}", _ "The following setting(s) were not saved:", _ Environment.NewLine, failedSettings) MessageBox.Show(message, "Unable to save settings", _ MessageBoxButtons.OK, MessageBoxIcon.Warning) End If End Sub
private void Form1_SettingsSaved(object sender, SettingsSavedEventArgs e) { // If any settings were not saved, display a list of them. if (e.FailedSettingsList.Count > 0) { String failedSettings = String.Join( Environment.NewLine, e.FailedSettingsList.ToArray()); String message = String.Format("{0}{1}{1}{2}", "The following setting(s) were not saved:", Environment.NewLine, failedSettings); MessageBox.Show(message, "Unable to save settings", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
Für C# fügen Sie folgenden Code am Ende der Form1_Load-Methode hinzu. Durch diesen Code wird die im letzten Schritt hinzugefügte Methode mit dem SettingsSaved-Ereignis verknüpft.
((ClientSettingsProvider)Properties.Settings.Default.Providers ["System.Web.ClientServices.Providers.ClientSettingsProvider"]) .SettingsSaved += new EventHandler<SettingsSavedEventArgs>(Form1_SettingsSaved);
Um die Anwendung jetzt zu testen, führen Sie sie mehrere Male sowohl als employee als auch als manager aus und geben unterschiedliche Werte in das Textfeld ein. Die Werte werden auf Einzelbenutzerbasis über mehrere Sitzungen beibehalten.
Implementieren der Abmeldung
Wenn der Benutzer das Kontrollkästchen Remember me bei der Anmeldung aktiviert, wird der Benutzer bei späteren Ausführungen automatisch von der Anwendung authentifiziert. Die automatische Authentifizierung wird fortgesetzt, während sich die Anmeldung im Offlinemodus befindet oder bis das Authentifizierungscookie abläuft. Zeitweise müssen jedoch mehrere Benutzer auf die Anwendung zugreifen, oder ein Einzelbenutzer meldet sich manchmal mit unterschiedlichen Anmeldeinformationen an. Um dieses Szenario zu ermöglichen, müssen Sie die Abmeldefunktionalität implementieren, wie im folgenden Verfahren beschrieben.
So implementieren Sie die Abmeldefunktionalität
Fügen Sie dem Formular im Form1-Designer ein Button-Steuerelement aus der ToolBox hinzu.
Geben Sie im Eigenschaftenfenster den (Name)-Wert logoutButton und den Text-Wert &Abmelden an.
Doppelklicken Sie auf logoutButton, um einen Click-Ereignishandler zu generieren.
Der Code-Editor wird angezeigt, wobei sich der Cursor innerhalb der logoutButton_Click-Methode befindet.
Ersetzen Sie die generierte logoutButton_Click-Methode durch folgenden Code:
Dieser Ereignishandler ruft zuerst die SaveSettings-Methode auf, die Sie im vorherigen Abschnitt hinzugefügt haben. Anschließend ruft der Ereignishandler die ClientFormsAuthenticationMembershipProvider.Logout-Methode auf. Wenn der Authentifizierungsdienst nicht verfügbar ist, löst die Logout-Methode eine WebException aus. In diesem Fall zeigt die logoutButton_Click-Methode eine Warnmeldung an und wechselt vorübergehend in den Offlinemodus, um den Benutzer abzumelden. Der Offlinemodus wird im nächsten Abschnitt beschrieben.
Durch die Abmeldung wird das lokale Authentifizierungscookie gelöscht, sodass beim Neustart der Anwendung eine Anmeldung erforderlich ist. Nach der Abmeldung wird die Anwendung vom Ereignishandler neu gestartet. Beim Neustart der Anwendung wird erst die Begrüßungsmeldung und dann das Anmeldedialogfeld angezeigt. Durch die Begrüßungsnachricht wird deutlich gemacht, dass die Anwendung neu gestartet wurde. Dadurch wird mögliche Verwirrung vermieden, wenn sich der Anwender anmelden muss, um Einstellungen zu speichern, und sich dann erneut anmelden muss, weil die Anwendung neu gestartet wurde.
Private Sub logoutButton_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles logoutButton.Click SaveSettings() Dim authProvider As ClientFormsAuthenticationMembershipProvider = _ CType(System.Web.Security.Membership.Provider, _ ClientFormsAuthenticationMembershipProvider) Try authProvider.Logout() Catch ex As WebException MessageBox.Show("Unable to access the authentication service." & _ Environment.NewLine & "Logging off locally only.", _ "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning) ConnectivityStatus.IsOffline = True authProvider.Logout() ConnectivityStatus.IsOffline = False End Try Application.Restart() End Sub
private void logoutButton_Click(object sender, EventArgs e) { SaveSettings(); ClientFormsAuthenticationMembershipProvider authProvider = (ClientFormsAuthenticationMembershipProvider) System.Web.Security.Membership.Provider; try { authProvider.Logout(); } catch (WebException ex) { MessageBox.Show("Unable to access the authentication service." + Environment.NewLine + "Logging off locally only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); ConnectivityStatus.IsOffline = true; authProvider.Logout(); ConnectivityStatus.IsOffline = false; } Application.Restart(); }
Um die Abmeldefunktionalität zu testen, führen Sie die Anwendung aus und wählen im Anmeldedialogfeld Remember me aus. Starten Sie dann die Anwendung neu, um sicherzustellen, dass Sie sich nicht mehr anmelden müssen. Starten Sie zum Schluss die Anwendung neu, indem Sie auf Abmelden klicken.
Aktivieren des Offlinemodus
Im folgenden Verfahren fügen Sie dem Formular ein Kontrollkästchen hinzu, um dem Benutzer das Aktivieren des Offlinemodus zu ermöglichen. Die Anwendung zeigt den Offlinemodus an, indem die staticConnectivityStatus.IsOffline-Eigenschaft auf true festgelegt wird. Der Offlinestatus wird auf der lokalen Festplatte gespeichert, und zwar an dem durch die Application.UserAppDataPath-Eigenschaft angegebenen Speicherort. Dies bedeutet, dass der Offlinestatus benutzer- und anwendungsgesteuert gespeichert wird.
Im Offlinemodus werden durch alle Anforderungen des Clientanwendungsdiensts Daten aus dem lokalen Cache abgerufen, anstatt zu versuchen, auf die Dienste zuzugreifen. In der Standardkonfiguration enthalten die lokalen Daten das Benutzerkennwort in verschlüsselter Form. Dies ermöglicht es dem Benutzer, sich anzumelden, während die Anwendung im Offlinemodus ist. Weitere Informationen finden Sie unter Gewusst wie: Konfigurieren von Clientanwendungsdiensten.
So aktivieren Sie den Offlinemodus in der Anwendung
Wählen Sie im Projektmappen-Explorer im Projekt ClientAppServicesDemo den Eintrag Form1 und dann Ansicht | Designer aus dem Visual Studio-Hauptmenü.
Fügen Sie dem Formular im Designer ein CheckBox-Steuerelement hinzu.
Geben Sie im Eigenschaftenfenster den (Name)-Wert workOfflineCheckBox und den Text-Wert &Offline arbeiten ein.
Klicken Sie im Eigenschaftenfenster auf die Schaltfläche Ereignisse.
Wählen Sie das CheckedChanged-Ereignis aus, und drücken Sie die EINGABETASTE, um einen Ereignishandler zu generieren.
Ersetzen Sie die generierte Methode durch folgenden Code.
Durch diesen Code wird der IsOffline-Wert aktualisiert und der Benutzer automatisch neu überprüft, sobald der Onlinemodus wieder aktiv ist. Die ClientFormsIdentity.RevalidateUser-Methode verwendet die zwischengespeicherten Anmeldeinformationen, sodass der Benutzer sich nicht explizit neu anmelden muss. Wenn der Authentifizierungsdienst nicht verfügbar ist, wird eine Warnmeldung angezeigt, und die Anwendung bleibt offline.
Tipp
Die RevalidateUser-Methode wird nur ergänzend bereitgestellt. Da sie über keinen Rückgabewert verfügt, kann sie nicht angeben, ob die erneute Validierung fehlgeschlagen ist. Die erneute Validierung kann beispielsweise fehlschlagen, wenn die Benutzeranmeldeinformationen auf dem Server geändert wurden. In diesem Fall können Sie Code hinzufügen, durch den Benutzer nach einem fehlgeschlagenen Dienstaufruf explizit überprüft werden. Weitere Informationen finden Sie im Abschnitt Zugriff auf Webeinstellungen weiter oben in dieser exemplarischen Vorgehensweise.
Nach der erneuten Validierung speichert dieser Code alle Änderungen an den lokalen Webeinstellungen, indem die zuvor hinzugefügte SaveSettings-Methode aufgerufen wird. Anschließend werden neue Werte auf dem Server abgerufen, indem die Reload-Methode der Settings-Klasse des Projekts (auf die in C# als Properties.Settings.Default und in Visual Basic als My.Settings zugegriffen wird) aufgerufen wird.
Private Sub workOfflineCheckBox_CheckedChanged( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles workOfflineCheckBox.CheckedChanged ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked If Not ConnectivityStatus.IsOffline Then Try ' Silently re-validate the user. CType(System.Threading.Thread.CurrentPrincipal.Identity, _ ClientFormsIdentity).RevalidateUser() ' If any settings have been changed locally, save the new ' new values to the Web settings service. SaveSettings() ' If any settings have not been changed locally, check ' the Web settings service for updates. My.Settings.Reload() Catch ex As WebException MessageBox.Show( _ "Unable to access the authentication service. " & _ Environment.NewLine + "Staying in offline mode.", _ "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning) workOfflineCheckBox.Checked = True End Try End If End Sub
private void workOfflineCheckBox_CheckedChanged( object sender, EventArgs e) { ConnectivityStatus.IsOffline = workOfflineCheckBox.Checked; if (!ConnectivityStatus.IsOffline) { try { // Silently re-validate the user. ((ClientFormsIdentity) System.Threading.Thread.CurrentPrincipal.Identity) .RevalidateUser(); // If any settings have been changed locally, save the new // new values to the Web settings service. SaveSettings(); // If any settings have not been changed locally, check // the Web settings service for updates. Properties.Settings.Default.Reload(); } catch (WebException) { MessageBox.Show( "Unable to access the authentication service. " + Environment.NewLine + "Staying in offline mode.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); workOfflineCheckBox.Checked = true; } } }
Fügen Sie folgenden Code am Ende der Form1_Load-Methode hinzu, um sicherzustellen, dass das Kontrollkästchen den aktuellen Verbindungsstatus anzeigt.
workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline
workOfflineCheckBox.Checked = ConnectivityStatus.IsOffline;
Damit ist die Beispielanwendung beendet. Um den Offlinebetrieb zu testen, führen Sie die Anwendung aus, melden sich als employee oder manager an und wählen Offline arbeiten. Ändern Sie den Wert im Textfeld, und schließen Sie die Anwendung. Starten Sie die Anwendung neu. Bevor Sie sich anmelden, klicken Sie mit der rechten Maustaste im Infobereich der Taskleiste auf das Symbol für den ASP.NET Development Server und klicken dann auf Beenden. Melden Sie sich dann wie üblich an. Auch wenn der Server nicht ausgeführt wird, können Sie sich anmelden. Ändern Sie den Wert im Textfeld, und starten Sie die Anwendung neu, um den geänderten Wert anzuzeigen.
Zusammenfassung
In dieser exemplarischen Vorgehensweise haben Sie gelernt, wie Sie Clientanwendungsdienste in einer Windows Forms-Anwendung aktivieren und verwenden. Nachdem Sie einen Testserver eingerichtet haben, haben Sie der Anwendung Code zum Authentifizieren der Benutzer sowie zum Abrufen von Benutzerrollen und Anwendungseinstellungen vom Server hinzugefügt. Außerdem haben Sie gelernt, wie Sie den Offlinemodus aktivieren, sodass die Anwendung anstelle von Remotediensten einen lokalen Datencache verwendet, wenn keine Verbindungen verfügbar sind.
Nächste Schritte
In einer realen Anwendung erfolgt der Zugriff auf Daten für zahlreiche Benutzer über einen Remoteserver, der u. U. nicht immer verfügbar ist oder unerwartet heruntergefahren wurde. Um eine stabile Anwendung zu entwickeln, müssen Sie angemessen auf Situationen reagieren, in denen der Dienst nicht verfügbar ist. Diese exemplarische Vorgehensweise umfasst Try-Catch-Blöcke zum Abfangen einer WebException sowie zum Anzeigen einer Fehlermeldung, wenn der Dienst nicht verfügbar ist. In Produktionscode würden Sie in diesem Fall möglicherweise in den Offlinemodus wechseln, die Anwendung beenden oder den Zugriff auf bestimmte Funktionen verweigern.
Um die Sicherheit der Anwendung zu erhöhen, sollten Sie Anwendung und Server vor der Bereitstellung eingehend testen.
Siehe auch
Aufgaben
Gewusst wie: Konfigurieren von Clientanwendungsdiensten
Exemplarische Vorgehensweise: Verwenden von ASP.NET-Anwendungsdiensten
Konzepte
Übersicht über Clientanwendungsdienste
Weitere Ressourcen
ASP.NET-Websiteverwaltungs-Tool
Erstellen und Konfigurieren der Datenbank für die Anwendungsdienste für SQL Server