Share via


Exemplarische Vorgehensweise: Verwenden des Authentifizierungsdiensts mit der Silverlight-Geschäftsanwendung

Mit der Vorlage "Silverlight-Geschäftsanwendung" erstellen Sie eine Projektmappe, in der Authentifizierung (mit der Formularauthentifizierung für den Authentifizierungsmodus), Rollen und Profile automatisch aktiviert sind. Die Projektmappe enthält Datenformulare für die Anmeldung vorhandener Benutzer und die Registrierung neuer Benutzer. Diese Funktionen können verwendet werden, ohne zusätzlichen Code zu schreiben. Sie können die Projektmappe anpassen, indem Sie Rollen und Profileigenschaften definieren.

In dieser exemplarischen Vorgehensweise erfahren Sie, wie Authentifizierung, Rollen und Profile in einer Silverlight-Geschäftsanwendung verwendet werden. Sie schränken den Zugriff auf bestimmte Domänenvorgänge anhand der Anmeldeinformationen des Benutzers ein und passen die Benutzeroberfläche basierend auf Benutzereinstellungen an. Zum Verwalten von Rollen und Benutzern in der Website wird das ASP.NET-Websiteverwaltungs-Tool verwendet.

Erforderliche Komponenten

Für diese und die anderen exemplarischen Vorgehensweisen in der RIA Services -Dokumentation müssen zusätzlich zu WCF RIA Services und dem WCF RIA Services-Toolkit mehrere erforderliche Programme installiert und korrekt konfiguriert werden, z. B. Visual Studio 2010, die Silverlight Developer-Laufzeit und das Silverlight-SDK. Zudem müssen Sie SQL Server 2008 R2 Express with Advanced Services installieren und konfigurieren und die AdventureWorks OLTP- und LT-Datenbanken installieren.

Ausführliche Anweisungen für jede dieser erforderlichen Komponenten finden Sie in den Themen unter Erforderliche Komponenten für WCF RIA Services. Folgen Sie den Anweisungen in diesen Themen, bevor Sie mit dieser exemplarischen Vorgehensweise fortfahren, um sicherzustellen, dass beim Ausführen der exemplarischen Vorgehensweisen für RIA Services so wenig Probleme wie möglich auftreten.

Erstellen von Benutzern und Rollen

Mithilfe der Funktionen in einer Silverlight-Geschäftsanwendung kann die Authentifizierung schnell implementiert werden. Im folgenden Abschnitt verwenden Sie das ASP.NET-Konfigurationstool, um einen Benutzer und eine Rolle zu erstellen und sich dann als dieser Benutzer anzumelden. Zudem registrieren Sie über das in der Silverlight-Geschäftsanwendung enthaltene Registrierungsformular einen neuen Benutzer.

So erstellen Sie eine Website, Rollen und Benutzer

  1. Wählen Sie in Visual Studio 2010 Datei, Neu und dann Projekt aus.

    Das Dialogfeld Neues Projekt wird angezeigt.

  2. Wählen Sie den Projekttyp Silverlight aus.

  3. Wählen Sie die Vorlage Silverlight-Geschäftsanwendung aus, und geben Sie für die Anwendung den Namen ExampleBusinessApplication ein.

    RIA_ServicesCreateBizApp

  4. Klicken Sie auf OK.

    Beachten Sie die erstellte Projektstruktur. Das Silverlight-Clientprojekt enthält Silverlight-Seiten im Ordner "Views". Diese Seiten ermöglichen das Anmelden von Benutzern und Registrieren von neuen Benutzern.

  5. Wählen Sie zum Öffnen des ASP.NET-Websiteverwaltungs-Tools zuerst das Serverprojekt (ExampleBusinessApplication.Web) im Projektmappen-Explorer aus. Öffnen Sie dann das Tool ASP.NET-Konfiguration.

  6. Wählen Sie im Menü Projekt die Option ASP.NET-Konfiguration aus.

    Wenn die Option "ASP.NET-Konfiguration" nicht im Menü "Projekt" angezeigt wird, haben Sie möglicherweise das Clientprojekt ausgewählt.

    RIA_OpenAdminTool

  7. Klicken Sie im ASP.NET-Websiteverwaltungs-Tool auf die Registerkarte Sicherheit.

    RIA_WebAdminSecurity

  8. Klicken Sie im Abschnitt Rollen auf den Link Rollen erstellen oder verwalten.

  9. Fügen Sie eine neue Rolle mit dem Namen "Managers" hinzu, und klicken Sie auf die Schaltfläche Rolle hinzufügen.

    WebAdmin_CreateRole

  10. Klicken Sie rechts unten auf die Schaltfläche Zurück.

  11. Klicken Sie im Abschnitt Benutzer auf den Link Benutzer erstellen.

  12. Erstellen Sie einen neuen Benutzer mit den folgenden Werten, und aktivieren Sie das Kontrollkästchen für die Rolle "Managers".

    Benutzername: CustomerManager

    Kennwort: P@ssword

    E-Mail: someone@example.com

    Sicherheitsfrage: Lieblingsfarbe?

    Sicherheitsantwort: Blau

    Rolle "Managers": aktiviert

    WebAdmin_CreateUser

  13. Klicken Sie auf die Schaltfläche Benutzer erstellen.

  14. Schließen Sie das ASP.NET-Websiteverwaltungs-Tool.

  15. Führen Sie die Projektmappe aus.

    Die Startseite für die Anwendung wird in einem Webbrowser angezeigt.

  16. Klicken Sie in der oberen rechten Ecke der Seite auf den Link Anmelden.

    Ein Dialogfeld "Anmelden" wird angezeigt.

  17. Geben Sie CustomerManager für den Benutzernamen und P@ssword für das Kennwort ein, und klicken Sie auf OK.

    RIA_LoginManager

    Sie werden als dieser Benutzer angemeldet. Beachten Sie den Text "Herzlich Willkommen CustomerManager" in der oberen rechten Ecke.

  18. Klicken Sie auf den Link Abmelden.

    Sie sind nicht mehr als CustomerManager angemeldet. In den folgenden Schritten erstellen Sie über das Registrierungsformular einen neuen Benutzer.

  19. Klicken Sie erneut auf den Link Anmelden.

  20. Klicken Sie im Dialogfeld "Anmelden" auf den Link Jetzt registrieren.

    Das Registrierungsformular wird angezeigt.

  21. Füllen Sie das Registrierungsformular aus, um ein neues Benutzerkonto zu erstellen. Verwenden Sie für den neuen Benutzer die folgenden Werte.

    Benutzername: SalesUser

    Anzeigename: SalesUser

    E-Mail: someone@example.com

    Kennwort: P@ssword

    Sicherheitsfrage: Welche Farbe hatte Ihr erstes Auto?

    Sicherheitsantwort: Grün

    RIA_RegisterUser

  22. Klicken Sie auf OK, um den neuen Benutzer zu erstellen.

    Beachten Sie, dass Sie jetzt als SalesUser angemeldet sind.

  23. Schließen Sie den Browser.

  24. Öffnen Sie erneut das ASP.NET-Websiteverwaltungs-Tool, und klicken Sie auf die Registerkarte Sicherheit.

    Beachten Sie, dass die Website jetzt zwei Benutzer enthält und zwei Rollen vorhanden sind, obwohl Sie nur eine Rolle erstellt haben.

  25. Klicken Sie auf Rollen erstellen oder verwalten. Sie sehen die Rollen "Managers" und "Registered Users".

    Die Rolle "Registered Users" wurde automatisch durch die Vorlage "Geschäftsanwendung" erstellt.

    RIA_ManageRoles

  26. Klicken Sie für "Registered Users" auf den Link Verwalten.

    Der Benutzer mit dem Namen "SalesUser", den Sie über die Anwendung hinzugefügt haben, ist in der Rolle "Registered Users" enthalten.

  27. Schließen Sie das ASP.NET-Websiteverwaltungs-Tool.

Definieren von Zugriffs- und Profileigenschaften

Zum Einschränken des Zugriffs auf einen Domänenvorgang wird das RequiresAuthenticationAttribute-Attribut oder das RequiresRoleAttribute-Attribut auf den Domänenvorgang angewendet. Domänenvorgänge ohne Attribut sind für alle Benutzer verfügbar. Durch das Anwenden eines Attributs auf einen Domänenvorgang wird nicht verhindert, dass der Benutzer den Domänenvorgang aufruft. Bei Benutzern ohne die erforderlichen Anmeldeinformationen führt der Aufruf jedoch zu einem Ausnahmefehler.

Einschränken der angezeigten Daten nach Rollen

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner "App_Data" im Serverprojekt, wählen Sie Hinzufügen aus und dann Vorhandenes Element.

  2. Fügen Sie im Dialogfeld "Vorhandenes Element hinzufügen" die AdventureWorksLT-Beispieldatenbank hinzu.

  3. Fügen Sie im Serverprojekt ein neues Element hinzu, und wählen Sie in den Datenvorlagen die Vorlage ADO.NET Entity Data Model aus.

  4. Geben Sie für das Modell den Namen "AdventureWorksModel.edmx" ein, und klicken Sie auf Hinzufügen.

    Der Assistent für Entity Data Model wird angezeigt.

  5. Wählen Sie die Option Aus Datenbank generieren aus, und klicken Sie dann auf Weiter.

  6. Wählen Sie die AdventureWorksLT-Datenbank aus, und klicken Sie anschließend auf Weiter.

  7. Wählen Sie in der Liste der Datenbankobjekte die Tabellen "Customer", "Product" und "SalesOrderHeader" aus, und klicken Sie dann auf Fertig stellen.

    Das Entity Data Model wird im Designer angezeigt.

  8. Erstellen Sie die Projektmappe.

  9. Fügen Sie im Serverprojekt ein neues Element hinzu, und wählen Sie in den Webvorlagen die Vorlage Domänendienstklasse aus.

  10. Geben Sie für den Domänendienst den Namen "AdventureWorksDomainService" ein, und klicken Sie dann auf Hinzufügen.

  11. Wählen Sie im Dialogfeld "Neue Domänendienstklasse hinzufügen" die Entitäten "Customer", "Product" und "SalesOrderHeader" aus.

    RIA_CreateDSForAuth

  12. Klicken Sie auf OK, um den Domänendienst zu erstellen.

  13. Fügen Sie in der AdventureWorksDomainService-Klassendatei der GetSalesOrderHeader-Methode das RequiresAuthenticationAttribute-Attribut hinzu.

    <RequiresAuthentication()> _
    Public Function GetSalesOrderHeaders() As IQueryable(Of SalesOrderHeader)
        Return Me.ObjectContext.SalesOrderHeaders
    End Function
    
    [RequiresAuthentication()]
    public IQueryable<SalesOrderHeader> GetSalesOrderHeaders()
    {
        return this.ObjectContext.SalesOrderHeaders;
    }
    
  14. Fügen Sie der GetCustomers-Methode das RequiresRoleAttribute-Attribut hinzu, und legen Sie den Namen der erforderlichen Rolle auf "Managers" fest.

    <RequiresRole("Managers")> _
    Public Function GetCustomers() As IQueryable(Of Customer)
        Return Me.ObjectContext.Customers
    End Function
    
    [RequiresRole("Managers")]
    public IQueryable<Customer> GetCustomers()
    {
        return this.ObjectContext.Customers;
    }
    

    Der GetProducts-Domänenvorgang steht allen Benutzern zur Verfügung, GetSalesOrderHeaders ist für authentifizierte Benutzer verfügbar und GetCustomers nur für Benutzer in der Rolle "Managers".

    Das folgende Beispiel zeigt den vollständigen Domänendienst.

    <EnableClientAccess()>  _
    Public Class AdventureWorksDomainService
        Inherits LinqToEntitiesDomainService(Of AdventureWorksLT_DataEntities)
    
        <RequiresRole("Managers")> _
        Public Function GetCustomers() As IQueryable(Of Customer)
            Return Me.ObjectContext.Customers
        End Function
    
        Public Function GetProducts() As IQueryable(Of Product)
            Return Me.ObjectContext.Products
        End Function
    
        <RequiresAuthentication()> _
        Public Function GetSalesOrderHeaders() As IQueryable(Of SalesOrderHeader)
            Return Me.ObjectContext.SalesOrderHeaders
        End Function
    End Class
    
    [EnableClientAccess()]
    public class AdventureWorksDomainService : LinqToEntitiesDomainService<AdventureWorksLT_DataEntities>
    {
        [RequiresRole("Managers")]
        public IQueryable<Customer> GetCustomers()
        {
            return this.ObjectContext.Customers;
        }
    
        public IQueryable<Product> GetProducts()
        {
            return this.ObjectContext.Products;
        }
    
        [RequiresAuthentication()]
        public IQueryable<SalesOrderHeader> GetSalesOrderHeaders()
        {
            return this.ObjectContext.SalesOrderHeaders;
        }
    }
    

Eine Profileigenschaft wird in der Datei "Web.config" definiert. Wenn Sie die Eigenschaft der User-Klasse auf dem Server hinzufügen, wird die entsprechende Eigenschaft für das Clientprojekt generiert.

Hinzufügen von Profileigenschaften

  1. Öffnen Sie im Serverprojekt die Datei "Web.config".

  2. Fügen Sie im <profile>-Element eine Profileigenschaft mit dem Namen "DefaultRows" hinzu. Die Eigenschaft enthält die Einstellung des Benutzers für die Anzahl anzuzeigender Zeilen.

    Das folgende Beispiel zeigt den Profilabschnitt der Datei "Web.config".

    <profile>
      <properties>
        <add name="FriendlyName" />
        <add type="System.Int32" defaultValue="10" name="DefaultRows"/>
      </properties>
    </profile>
    
  3. Speichern Sie die Datei "Web.config".

  4. Erweitern Sie im Serverprojekt den Ordner "Models".

  5. Öffnen Sie die Datei "User.cs" bzw. "User.vb", und fügen Sie eine Eigenschaft mit dem Namen "DefaultRows" hinzu.

    Imports System.ServiceModel.DomainServices.Server.ApplicationServices
    Imports System.Runtime.Serialization
    Namespace Web
        Partial Public Class User
            Inherits UserBase
    
            Public Property FriendlyName As String
    
            Public Property DefaultRows As Integer
    
        End Class
    End Namespace
    
    namespace ExampleBusinessApplication.Web
    {
        using System.Runtime.Serialization;
        using System.ServiceModel.DomainServices.Server.ApplicationServices;
    
        public partial class User : UserBase
        {
            public string FriendlyName { get; set; }
    
            public int DefaultRows { get; set; }
        }
    }
    

Verwenden des Authentifizierungsdiensts im Clientprojekt

Bevor Sie einen Domänenvorgang mit eingeschränkten Berechtigungen aufrufen, sollten Sie sicherstellen, dass der Benutzer über die erforderlichen Anmeldeinformationen verfügt. Andernfalls wird ein Ausnahmefehler ausgelöst. Im folgenden Abschnitt überprüfen Sie die Anmeldeinformationen des Benutzers, und Sie füllen drei DataGrid-Steuerelemente anhand der Anmeldeinformationen des Benutzers auf. Zudem rufen Sie die Anzahl von Datensätzen basierend auf einer Eigenschaft im Benutzerprofil ab. Für nicht authentifizierte Benutzer wird der Standardwert 10 verwendet. Dieser Abschnitt enthält keine Methode, mit der Benutzer die DefaultRows-Profileigenschaft festlegen können. Eine solche Eigenschaft wird jedoch in einem späteren Abschnitt hinzugefügt.

Hinzufügen einer Silverlight-Seite zum Anzeigen von Daten

  1. Fügen Sie im Clientprojekt dem Ordner "Views" ein neues Element hinzu.

  2. Wählen Sie die Vorlage Silverlight-Seite aus, und geben Sie für die neue Seite den Namen "Reports.xaml" ein.

  3. Öffnen Sie die Datei "MainPage.xaml", und fügen Sie einen Link für die Seite "Reports" hinzu, indem Sie nach dem HyperlinkButton mit dem Namen Link2 für die Infoseite (About) den folgenden XAML-Code hinzufügen.

    <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
    
    <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" 
           NavigateUri="/Reports" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>
    
  4. Öffnen Sie im Ordner "Assets\Resources" die Datei "ApplicationStrings.resx".

  5. Fügen Sie eine neue Zeichenfolgenressource "ReportsPageTitle" mit dem Wert "Reports" hinzu.

    RIA_AddReportResource

  6. Speichern und schließen Sie die Datei "ApplicationStrings.resx".

  7. Öffnen Sie die Datei "Reports.xaml", und fügen Sie dem Grid-Element den folgenden XAML-Code hinzu, um die Seite entsprechend den anderen Seiten der Website zu formatieren.

    <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">
        <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
            <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
                       Text="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>
            <TextBlock x:Name="ContentText" Style="{StaticResource ContentTextStyle}"
                       Text="Display reports based on user permissions"/>
    
        </StackPanel>
    </ScrollViewer>
    
  8. Ziehen Sie drei DataGrid-Steuerelemente aus der Toolbox direkt vor das Endtag des Stapelbereichs mit dem Namen ContentStackPanel.

    Wenn Sie die DataGrid-Steuerelemente aus der Toolbox ziehen, wird dem Projekt ein Verweis auf die System.Windows.Controls.Data-Assembly hinzugefügt, und der Seite wird ein Präfix für den System.Windows.Controls-Namespace hinzugefügt.

  9. Geben Sie für die DataGrid-Steuerelemente die Namen ProductsGrid, SalesOrdersGrid und CustomersGrid ein.

  10. Legen Sie für jedes DataGrid-Steuerelement die Margin-Eigenschaft auf 5 fest.

    Das folgende Beispiel zeigt die vollständige Datei "Reports.xaml".

    <navigation:Page x:Class="ExampleBusinessApplication.Views.Reports"
               xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
               mc:Ignorable="d"
               xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               d:DesignWidth="640" d:DesignHeight="480"
               Title="Reports Page" >
        <Grid x:Name="LayoutRoot">
            <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">
                <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
                    <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
                               Text="{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}"/>
                    <TextBlock x:Name="ContentText" Style="{StaticResource ContentTextStyle}"
                               Text="Display reports based on user permissions"/>
                    <data:DataGrid Name="ProductsGrid" Margin="5" />
                    <data:DataGrid Name="SalesOrdersGrid" Margin="5" />
                    <data:DataGrid Name="CustomersGrid" Margin="5" />
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </navigation:Page>
    
  11. Öffnen Sie die Datei "Reports.xaml.cs" bzw. "Reports.xaml.vb".

  12. Fügen Sie für C# using-Anweisungen für die Namespaces System.ServiceModel.DomainServices.Client, System.ServiceModel.DomainServices.Client.ApplicationServices und ExampleBusinessApplication.Web hinzu. Fügen Sie für Visual Basic Imports-Anweisungen für die Namespaces System.ServiceModel.DomainServices.Client, System.ServiceModel.DomainServices.Client.ApplicationServices, System.Windows.Controls und ExampleBusinessApplication.Web hinzu.

  13. Erstellen Sie eine Instanz des AdventureWorksDomainContext-Kontexts und eine Variable mit dem Namen "numberOfRows", die die Anzahl abzurufender Zeilen enthält.

    Private context As New AdventureWorksDomainContext
    Private numberOfRows As Integer = 10
    
    private AdventureWorksDomainContext context = new AdventureWorksDomainContext();
    int numberOfRows = 10;
    
  14. Fügen Sie eine Methode mit dem Namen LoadRestrictedReports hinzu, durch die die GetSalesOrderHeaderQuery- und die GetCustomersQuery-Methode aufgerufen und die entsprechenden Datenraster mit den Ergebnissen aufgefüllt werden, wenn der Benutzer der Rolle "Managers" angehört.

    Wenn Sie einen Domänenvorgang aufrufen und der Benutzer nicht über die erforderlichen Anmeldeinformationen verfügt, gibt der Domänenvorgang eine Ausnahme zurück. Sie können diese Situation vermeiden, indem Sie die Anmeldeinformationen vor dem Aufrufen des Domänenvorgangs überprüfen.

    Private Sub LoadRestrictedReports()
        Dim loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows))
        SalesOrdersGrid.ItemsSource = loadSales.Entities
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible
    
        If (WebContext.Current.User.IsInRole("Managers")) Then
            Dim loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows))
            CustomersGrid.ItemsSource = loadCustomers.Entities
            CustomersGrid.Visibility = System.Windows.Visibility.Visible
        Else
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
        End If
    End Sub
    
    private void LoadRestrictedReports()
    {
        LoadOperation<SalesOrderHeader> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
        SalesOrdersGrid.ItemsSource = loadSales.Entities;
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;
    
        if (WebContext.Current.User.IsInRole("Managers"))
        {
            LoadOperation<Customer> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
            CustomersGrid.ItemsSource = loadCustomers.Entities;
            CustomersGrid.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
        }
    }
    
  15. Fügen Sie eine Methode mit dem Namen LoadReports hinzu, durch die überprüft wird, ob der Benutzer authentifiziert ist, und ob die LoadRestrictedReports-Methode aufgerufen wird, wenn dies der Fall ist. Diese Methode ruft auch die DefaultRows-Profileigenschaft ab und fügt dem User-Objekt einen Ereignishandler für das PropertyChanged-Ereignis hinzu. Zum Schluss ruft sie die GetProductsQuery-Methode für alle Benutzer auf.

    Private Sub LoadReports()
        If (WebContext.Current.User.IsAuthenticated) Then
            numberOfRows = WebContext.Current.User.DefaultRows
            AddHandler WebContext.Current.User.PropertyChanged, AddressOf User_PropertyChanged
            LoadRestrictedReports()
        Else
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
            SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed
        End If
    
        Dim loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows))
        ProductsGrid.ItemsSource = loadProducts.Entities
    End Sub
    
    private void LoadReports()
    {
        if (WebContext.Current.User.IsAuthenticated)
        {
            numberOfRows = WebContext.Current.User.DefaultRows;
            WebContext.Current.User.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged);
            LoadRestrictedReports();
        }
        else
        {
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
            SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
        }
    
        LoadOperation<Product> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows));
        ProductsGrid.ItemsSource = loadProducts.Entities;
    }
    
  16. Fügen Sie einen Ereignishandler für das PropertyChanged-Ereignis hinzu, durch den LoadReports aufgerufen wird, wenn sich die DefaultRows-Eigenschaft geändert hat.

    Private Sub User_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs)
        If (e.PropertyName = "DefaultRows") Then
            LoadReports()
        End If
    End Sub
    
    void User_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "DefaultRows")
        {
            LoadReports();
        }
    }
    
  17. Fügen Sie Ereignishandler für die LoggedIn- und LoggedOut-Ereignisse hinzu, durch die Daten basierend auf der Änderung der Anmeldeinformationen für die Benutzerauthentifizierung geladen oder ausgeblendet werden.

    Private Sub Authentication_LoggedIn(ByVal sender As Object, ByVal e As ApplicationServices.AuthenticationEventArgs)
        LoadReports()
    End Sub
    
    Private Sub Authentication_LoggedOut(ByVal sender As Object, ByVal e As ApplicationServices.AuthenticationEventArgs)
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed
    End Sub
    
    void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
    {
        LoadReports();
    }
    
    void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
    {
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
        SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
    }
    
  18. Fügen Sie dem Konstruktor den folgenden Code hinzu. Dieser Code lädt die Handler und ruft LoadReports auf.

    Public Sub New()
        InitializeComponent()
    
        Me.Title = ApplicationStrings.ReportsPageTitle
    
        AddHandler WebContext.Current.Authentication.LoggedIn, AddressOf Authentication_LoggedIn
        AddHandler WebContext.Current.Authentication.LoggedOut, AddressOf Authentication_LoggedOut
    
        LoadReports()
    End Sub
    
    public Reports()
    {
        InitializeComponent();
    
        this.Title = ApplicationStrings.ReportsPageTitle;
    
        WebContext.Current.Authentication.LoggedIn += new System.EventHandler<AuthenticationEventArgs>(Authentication_LoggedIn);
        WebContext.Current.Authentication.LoggedOut += new System.EventHandler<AuthenticationEventArgs>(Authentication_LoggedOut);
    
        LoadReports();
    }
    

    Das folgende Beispiel zeigt die vollständige Codedatei.

    Imports System.Windows.Navigation
    Imports System.Windows.Controls
    Imports System.ServiceModel.DomainServices.Client
    Imports System.ServiceModel.DomainServices.Client.ApplicationServices
    Imports ExampleBusinessApplication.Web
    
    Partial Public Class Reports
        Inherits Page
    
        Private context As New AdventureWorksDomainContext
        Private numberOfRows As Integer = 10
    
        Public Sub New()
            InitializeComponent()
    
            Me.Title = ApplicationStrings.ReportsPageTitle
    
            AddHandler WebContext.Current.Authentication.LoggedIn, AddressOf Authentication_LoggedIn
            AddHandler WebContext.Current.Authentication.LoggedOut, AddressOf Authentication_LoggedOut
    
            LoadReports()
        End Sub
    
        Private Sub LoadReports()
            If (WebContext.Current.User.IsAuthenticated) Then
                numberOfRows = WebContext.Current.User.DefaultRows
                AddHandler WebContext.Current.User.PropertyChanged, AddressOf User_PropertyChanged
                LoadRestrictedReports()
            Else
                CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
                SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed
            End If
    
            Dim loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows))
            ProductsGrid.ItemsSource = loadProducts.Entities
        End Sub
    
        Private Sub LoadRestrictedReports()
            Dim loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows))
            SalesOrdersGrid.ItemsSource = loadSales.Entities
            SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible
    
            If (WebContext.Current.User.IsInRole("Managers")) Then
                Dim loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows))
                CustomersGrid.ItemsSource = loadCustomers.Entities
                CustomersGrid.Visibility = System.Windows.Visibility.Visible
            Else
                CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
            End If
        End Sub
    
        Private Sub User_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs)
            If (e.PropertyName = "DefaultRows") Then
                LoadReports()
            End If
        End Sub
    
        Private Sub Authentication_LoggedIn(ByVal sender As Object, ByVal e As ApplicationServices.AuthenticationEventArgs)
            LoadReports()
        End Sub
    
        Private Sub Authentication_LoggedOut(ByVal sender As Object, ByVal e As ApplicationServices.AuthenticationEventArgs)
            CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
            SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed
        End Sub
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;
    using System.ServiceModel.DomainServices.Client;
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using ExampleBusinessApplication.Web;
    
    namespace ExampleBusinessApplication.Views
    {
        public partial class Reports : Page
        {
            private AdventureWorksDomainContext context = new AdventureWorksDomainContext();
            int numberOfRows = 10;
    
            public Reports()
            {
                InitializeComponent();
    
                this.Title = ApplicationStrings.ReportsPageTitle;
    
                WebContext.Current.Authentication.LoggedIn += new System.EventHandler<AuthenticationEventArgs>(Authentication_LoggedIn);
                WebContext.Current.Authentication.LoggedOut += new System.EventHandler<AuthenticationEventArgs>(Authentication_LoggedOut);
    
                LoadReports();
            }
    
            private void LoadReports()
            {
                if (WebContext.Current.User.IsAuthenticated)
                {
                    numberOfRows = WebContext.Current.User.DefaultRows;
                    WebContext.Current.User.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged);
                    LoadRestrictedReports();
                }
                else
                {
                    CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                    SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
                }
    
                LoadOperation<Product> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows));
                ProductsGrid.ItemsSource = loadProducts.Entities;
            }
    
            private void LoadRestrictedReports()
            {
                LoadOperation<SalesOrderHeader> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
                SalesOrdersGrid.ItemsSource = loadSales.Entities;
                SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;
    
                if (WebContext.Current.User.IsInRole("Managers"))
                {
                    LoadOperation<Customer> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
                    CustomersGrid.ItemsSource = loadCustomers.Entities;
                    CustomersGrid.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
    
            void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
            {
                LoadReports();
            }
    
            void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
            {
                CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
                SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed;
            }
    
            void User_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "DefaultRows")
                {
                    LoadReports();
                }
            }
        }
    }
    
  19. Führen Sie die Projektmappe aus.

  20. Klicken Sie auf den Link Reports.

    Wenn Sie nicht angemeldet sind, wird nur die Tabelle "Products" auf der Seite "Reports" angezeigt.

  21. Klicken Sie auf den Link "Anmelden", und melden Sie sich als SalesUser an.

    Die Tabellen für Produkte und Verkaufsaufträge werden angezeigt.

    RIA_DisplayReports

  22. Melden Sie sich ab, und melden Sie sich als CustomerManager an.

    Die Tabellen für Produkte, Verkaufsaufträge und Kunden werden angezeigt.

  23. Schließen Sie den Webbrowser.

Sie können ein untergeordnetes Fenster hinzufügen, um Benutzern das Bearbeiten der DefaultRows-Profileigenschaft zu ermöglichen. Wenn der Wert geändert wird, rufen Sie die SaveUser-Methode auf, um den Wert in der Datenquelle zu speichern. Der aktuelle Wert wird über die Eigenschaften des User-Objekts der aktuellen WebContext-Instanz abgerufen.

Hinzufügen eines Fensters zum Festlegen der Profileigenschaft

  1. Fügen Sie im Clientprojekt dem Ordner "Views" ein neues Element hinzu.

  2. Wählen Sie die Vorlage Untergeordnetes Silverlight-Fenster aus, und geben Sie für das untergeordnete Fenster den Namen "ProfileWindow.xaml" ein.

    Untergeordnetes Fenster hinzufügen

  3. Klicken Sie auf die Schaltfläche Hinzufügen.

  4. Fügen Sie in der Datei "ProfileWindow.xaml" nach dem Grid.RowDefinitions-Element den folgenden XAML-Code hinzu, um eine ComboBox zum Auswählen der in den Berichten anzuzeigenden Anzahl von Zeilen hinzuzufügen.

    <StackPanel Orientation="Horizontal" Grid.Row="0">
        <TextBlock Text="Number of rows to display for reports: "></TextBlock>
        <ComboBox x:Name="defaultRows" Height="20" VerticalAlignment="Top">
            <ComboBoxItem Content="1"></ComboBoxItem>
            <ComboBoxItem Content="2"></ComboBoxItem>
            <ComboBoxItem Content="3"></ComboBoxItem>
            <ComboBoxItem Content="4"></ComboBoxItem>
            <ComboBoxItem Content="5"></ComboBoxItem>
            <ComboBoxItem Content="6"></ComboBoxItem>
            <ComboBoxItem Content="7"></ComboBoxItem>
            <ComboBoxItem Content="8"></ComboBoxItem>
            <ComboBoxItem Content="9"></ComboBoxItem>
            <ComboBoxItem Content="10"></ComboBoxItem>
            <ComboBoxItem Content="15"></ComboBoxItem>
            <ComboBoxItem Content="20"></ComboBoxItem>
        </ComboBox>
    </StackPanel>
    
  5. Legen Sie die Title-Eigenschaft für das ChildWindow auf Select Preferences fest.

  6. Fügen Sie in der Datei "ProfileWindow.xaml.cs" bzw. "ProfileWindow.xaml.vb" den folgenden Code hinzu, um die Profileigenschaft abzurufen und festzulegen.

    Imports System.Windows.Controls
    Imports System.Windows
    
    Partial Public Class ProfileWindow
        Inherits ChildWindow
    
        Public Sub New()
            InitializeComponent()
    
            Dim userDefaultRows = WebContext.Current.User.DefaultRows.ToString()
            For Each cbi As ComboBoxItem In defaultRows.Items
                If (cbi.Content.ToString() = userDefaultRows) Then
                    defaultRows.SelectedItem = cbi
                    Exit For
                End If
            Next
        End Sub
    
        Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
            Dim newSelection = Integer.Parse(defaultRows.SelectionBoxItem.ToString())
            If (newSelection <> WebContext.Current.User.DefaultRows) Then
                WebContext.Current.User.DefaultRows = newSelection
                WebContext.Current.Authentication.SaveUser(True)
            End If
            Me.DialogResult = True
        End Sub
    
        Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles CancelButton.Click
            Me.DialogResult = False
        End Sub
    
    End Class
    
    public partial class ProfileWindow : ChildWindow
    {
        public ProfileWindow()
        {
            InitializeComponent();
    
            string userDefaultRows = WebContext.Current.User.DefaultRows.ToString();
            foreach (ComboBoxItem cbi in defaultRows.Items)
            {
                if (cbi.Content.ToString() == userDefaultRows)
                {
                    defaultRows.SelectedItem = cbi;
                    break;
                }
            }
        }
    
        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            int newSelection = int.Parse(defaultRows.SelectionBoxItem.ToString());
            if (newSelection != WebContext.Current.User.DefaultRows)
            {
                WebContext.Current.User.DefaultRows = newSelection;
                WebContext.Current.Authentication.SaveUser(true);
            }
            this.DialogResult = true;
        }
    
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
    }
    
  7. Fügen Sie für Visual Basic Imports-Anweisungen für die Namespaces System.Windows.Controls und System.Windows hinzu.

  8. Erweitern Sie den Ordner "Views\Login", und öffnen Sie die Datei "LoginStatus.xaml".

  9. Fügen Sie vor der Abmeldeschaltfläche den folgenden XAML-Code hinzu, um dem Profilfenster einen Einstellungslink hinzuzufügen.

    <Button x:Name="SettingsButton" Click="SettingsButton_Click" Content="settings" Style="{StaticResource LoginRegisterLinkStyle}" Margin="0,0,0,0"></Button>
    <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
    
  10. Fügen Sie in der Datei "LoginStatus.xaml.cs" bzw. "LoginStatus.xaml.vb" den folgenden Click-Ereignishandler für den Einstellungslink hinzu.

    Private Sub SettingsButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim settingsWindow As New ProfileWindow
        settingsWindow.Show()
    End Sub
    
    private void SettingsButton_Click(object sender, RoutedEventArgs e)
    {
        ExampleBusinessApplication.Views.ProfileWindow settingsWindow = new ExampleBusinessApplication.Views.ProfileWindow();
        settingsWindow.Show();
    }
    
  11. Führen Sie die Projektmappe aus.

  12. Melden Sie sich als CustomerManager oder SalesUser an. Sie werden feststellen, dass die Anmeldestatusleiste jetzt einen Link für Einstellungen enthält.

    RIA_NewLoginStatusBar

  13. Klicken Sie auf den Einstellungslink, und legen Sie die Standardanzahl von Zeilen fest, die für die Berichte angezeigt werden soll.

    RIA_ShowProfileSettings

  14. Öffnen Sie die Seite "Reports". Das DataGrid enthält jetzt die von Ihnen ausgewählte Anzahl von Zeilen.