次の方法で共有


チュートリアル: Silverlight ビジネス アプリケーションでの認証サービスの使用

Silverlight ビジネス アプリケーション テンプレートにより、(認証モードにフォーム認証を使用した) 認証、ロール、およびプロファイルを自動的に有効にするソリューションが作成されます。このソリューションには、既存のユーザーにログインしたり、新しいユーザーを登録したりするためのデータ フォームが含まれています。このような機能は、追加のコードを記述しなくても使用できます。ロールおよびプロファイル プロパティを定義することで、ソリューションをカスタマイズできます。

このチュートリアルでは、Silverlight ビジネス アプリケーションで認証、ロール、およびプロファイルを使用する方法について説明します。ユーザーの資格情報に基づいて特定のドメイン操作へのアクセスを制限し、ユーザー設定に基づいてユーザー インターフェイスをカスタマイズします。サイト内のロールおよびユーザーを管理する場合は ASP.NET Web サイト管理ツールを使用します。

前提条件

このチュートリアル、および RIA サービス のドキュメントで紹介されている他のチュートリアルでは、WCF RIA サービス および WCF RIA サービス Toolkit に加え、Visual Studio 2010 や Silverlight の開発者向けランタイムと SDK など、前提条件となっているいくつかのプログラムが適切にインストールおよび構成されている必要があります。また、SQL Server 2008 R2 Express with Advanced Services をインストールして構成し、AdventureWorks OLTP と LT データベースをインストールすることも必要です。

これらの各前提条件を満たしているかどうかを確認するための詳細な手順については、「WCF RIA Services の前提条件」ノード内のトピックを参照してください。このチュートリアルを進める前に、トピックに記載されている手順に従って、この RIA サービス チュートリアルを実行するときに発生する問題をできるだけ最小限に抑えるようにします。

ユーザーおよびロールの作成

Silverlight ビジネス アプリケーションに用意されている機能を使用すると、認証を簡単に実装できます。次のセクションでは、ASP.NET 構成ツールを使用してユーザーとロールを作成し、そのユーザーとしてログインします。Silverlight ビジネス アプリケーションに用意されている登録フォームを使用して新しいユーザーを登録します。

サイト、ロール、およびユーザーを作成するには

  1. Visual Studio 2010 で、[ファイル][新規作成][プロジェクト] の順に選択します。

    [新しいプロジェクト] ダイアログ ボックスが表示されます。

  2. プロジェクトの種類に [Silverlight] を選択します。

  3. テンプレートに [Silverlight ビジネス アプリケーション] を選択し、アプリケーションに ExampleBusinessApplication という名前を付けます。

    RIA_ServicesCreateBizApp

  4. [OK] をクリックします。

    作成されたプロジェクトの構造を確認します。Silverlight クライアント プロジェクトでは Views フォルダー内の Silverlight ページが含まれています。これらのページでは、ユーザーにログインしたり、新しいユーザーを登録したりできます。

  5. ASP.NET Web サイト管理ツールを開くには、まずソリューション エクスプローラーでサーバー プロジェクト (ExampleBusinessApplication.Web) を選択し、ASP.NET 構成ツールを開きます。

  6. [プロジェクト] メニューの [ASP.NET 構成] をクリックします。

    [プロジェクト] メニューに [ASP.NET 構成] オプションが表示されていない場合は、クライアント プロジェクトを選択している可能性があります。

    RIA_OpenAdminTool

  7. ASP.NET Web サイト管理ツールの [セキュリティ] タブをクリックします。

    RIA_WebAdminSecurity

  8. [ロール] セクションで、[ロールの作成または管理] リンクをクリックします。

  9. Managers という名前の新しいロールを追加し、[ロールの追加] をクリックします。

    WebAdmin_CreateRole

  10. 右下隅の [戻る] をクリックします。

  11. [ユーザー] セクションで、[ユーザーの作成] リンクをクリックします。

  12. 次の値を使用して新しいユーザーを作成し、Managers ロールのチェック ボックスをオンにします。

    ユーザー名: CustomerManager

    パスワード: P@ssword

    電子メール: someone@example.com

    秘密の質問: 好きな色は?

    秘密の答え: 青

    Managers ロール: オン

    WebAdmin_CreateUser

  13. [ユーザーの作成] をクリックします。

  14. ASP.NET Web サイト管理ツールを閉じます。

  15. ソリューションを実行します。

    アプリケーションのホーム ページが Web ブラウザーに表示されます。

  16. ページの右上隅にある [ログイン] リンクをクリックします。

    [ログイン] ダイアログ ボックスが表示されます。

  17. ユーザー名に「CustomerManager」、パスワードに「P@ssword」と入力し、[OK] をクリックします。

    RIA_LoginManager

    これで、そのユーザーとしてログインします。"ようこそ CustomerManager" というテキストが右上隅に表示されています。

  18. [ログアウト] リンクをクリックします。

    これで、CustomerManager としてログインしていない状態になりました。次の手順では、登録フォームを使用して新しいユーザーを作成します。

  19. [ログイン] リンクを再びクリックします。

  20. [ログイン] ダイアログ ボックスで、[今すぐ登録] リンクをクリックします。

    登録フォームが表示されます。

  21. 登録フォームに入力して、新しいユーザー アカウントを作成します。新しいユーザーには次の値を使用します。

    ユーザー名: SalesUser

    表示名: SalesUser

    電子メール: someone@example.com

    パスワード: P@ssword

    秘密の質問: 最初の自動車の色は?

    秘密の答え: 緑

    RIA_RegisterUser

  22. [OK] をクリックすると、新しいユーザーが作成されます。

    ここで、SalesUser としてログインしていることがわかります。

  23. ブラウザーを閉じます。

  24. ASP.NET Web サイト管理ツールを再度開き、[セキュリティ] タブをクリックします。

    サイトに 2 人のユーザーが存在し、作成したロールが 1 つだけの場合でも 2 つのロールが存在します。

  25. [ロールの作成または管理] をクリックし、Managers ロールと登録済みユーザーを確認します。

    登録済みユーザー ロールは、ビジネス アプリケーション テンプレートによって自動的に作成されました。

    RIA_ManageRoles

  26. 登録済みユーザーの場合は、[管理] リンクをクリックします。

    アプリケーションを使用して追加した SalesUser という名前のユーザーが登録済みユーザー ロールに属していることがわかります。

  27. ASP.NET Web サイト管理ツールを閉じます。

アクセスおよびプロファイル プロパティの定義

ドメイン操作へのアクセスを制限するには、ドメイン操作に RequiresAuthenticationAttribute 属性または RequiresRoleAttribute 属性を適用します。属性を持たないドメイン操作は、すべてのユーザーが使用できます。属性をドメイン操作に適用しても、ユーザーがドメイン操作を呼び出せなくなることはありませんが、必要な資格情報を持っていないユーザーの場合は、例外が発生します。

ロールごとに表示データを制限する

  1. ソリューション エクスプローラーで、サーバー プロジェクト内の App_Data フォルダーを右クリックし、[追加][既存の項目] の順にクリックします。

  2. [既存項目の追加] ダイアログ ボックスで、AdventureWorksLT サンプル データベースを追加します。

  3. サーバー プロジェクトで、新しい項目を追加し、[データ] テンプレートから [ADO.NET エンティティ データ モデル] テンプレートをクリックします。

  4. モデルに AdventureWorksModel.edmx という名前を付けて、[追加] をクリックします。

    Entity Data Model ウィザードが表示されます。

  5. [データベースから生成] を選択し、[次へ] をクリックします。

  6. AdventureWorksLT データベースを選択し、[次へ] をクリックします。

  7. データベース オブジェクトの一覧から、Customer、Product、および SalesOrderHeader の各テーブルを選択し、[完了] をクリックします。

    エンティティ データ モデルがデザイナーに表示されます。

  8. ソリューションをビルドします。

  9. サーバー プロジェクトで、新しい項目を追加し、[Web] テンプレートから [DomainService クラス] テンプレートをクリックします。

  10. ドメイン サービスに AdventureWorksDomainService という名前を付けて、[追加] をクリックします。

  11. [新しいドメイン サービス クラスの追加] ダイアログ ボックスで、Customer、Product、および SalesOrderHeader エンティティを選択します。

    RIA_CreateDSForAuth

  12. [OK] をクリックして、ドメイン サービスの作成を完了します。

  13. AdventureWorksDomainService クラス ファイルで、RequiresAuthenticationAttribute 属性を GetSalesOrderHeader メソッドに追加します。

    <RequiresAuthentication()> _
    Public Function GetSalesOrderHeaders() As IQueryable(Of SalesOrderHeader)
        Return Me.ObjectContext.SalesOrderHeaders
    End Function
    
    [RequiresAuthentication()]
    public IQueryable<SalesOrderHeader> GetSalesOrderHeaders()
    {
        return this.ObjectContext.SalesOrderHeaders;
    }
    
  14. RequiresRoleAttribute 属性を GetCustomers メソッドに追加し、必要なロールの名前を "Managers" に設定します。

    <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;
    }
    

    GetProducts ドメイン操作は、すべてのユーザーが使用できます。GetSalesOrderHeaders は認証済みユーザー、GetCustomers は Managers ロールのユーザーのみが使用できます。

    完全なドメイン サービスを次に示します。

    <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;
        }
    }
    

Web.config ファイルでプロファイル プロパティを定義します。このプロパティをサーバー上のユーザー クラスに追加すると、クライアント プロジェクトに対して対応するプロパティが生成されます。

プロファイル プロパティを追加する

  1. サーバー プロジェクトで Web.config ファイルを開きます。

  2. <profile> 要素に、DefaultRows という名前のプロファイル プロパティを追加します。このプロパティには、表示する行数に関するユーザー設定が含まれています。

    Web.config ファイルのプロファイル セクションを次に示します。

    <profile>
      <properties>
        <add name="FriendlyName" />
        <add type="System.Int32" defaultValue="10" name="DefaultRows"/>
      </properties>
    </profile>
    
  3. Web.config ファイルを保存します。

  4. サーバー プロジェクトで、Models フォルダーを展開します。

  5. User.cs ファイルまたは User.vb ファイルを開き、DefaultRows という名前のプロパティを追加します。

    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; }
        }
    }
    

クライアントからの認証サービスの使用

アクセス許可が制限されたドメイン操作を呼び出す前に、ユーザーに必要な資格情報があることを確認する必要があります。必要な資格情報がない場合は、例外がスローされます。次のセクションで、ユーザーの資格情報を確認し、ユーザーの資格情報に基づいて 1 ~ 3 つの DataGrid コントロールから設定します。また、ユーザー プロファイルのプロパティに基づいてレコードの数を取得します。既定値の 10 は、認証されていないユーザーに使用されます。このセクションでは、ユーザーが DefaultRows プロファイル プロパティを設定するための方法は説明しませんが、このプロファイル プロパティは後のセクションで追加します。

データを表示するための Silverlight ページを追加する

  1. クライアント プロジェクトで、Views フォルダーに新しい項目を追加します。

  2. [Silverlight ページ] テンプレートを選択し、新しいページに Reports.xaml という名前を付けます。

  3. MainPage.xaml ファイルを開き、バージョン情報ページにリンクする Link2 という名前の HyperlinkButton の後に次の XAML を追加して、Reports ページのリンクを追加します。

    <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. Assets\Resources フォルダーで、ApplicationStrings.resx ファイルを開きます。

  5. ReportsPageTitle という名前の新しい文字列リソースを、値を Reports に設定して追加します。

    RIA_AddReportResource

  6. ApplicationStrings.resx ファイルを保存して閉じます。

  7. Reports.xaml ファイルを開き、Grid 要素に次の XAML を追加して、サイト内の他のページの形式と一致させます。

    <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. ContentStackPanel という名前のスタック パネルの終了タグの直前に、ツールボックスから 3 つの DataGrid コントロールをドラッグします。

    ツールボックスから DataGrid コントロールをドラッグすると、System.Windows.Controls.Data アセンブリへの参照がプロジェクトに追加され、System.Windows.Controls 名前空間のプレフィックスがページに追加されます。

  9. DataGrid コントロールに ProductsGridSalesOrdersGrid、および CustomersGrid という名前を付けます。

  10. DataGrid コントロールごとに、Margin プロパティを 5 に設定します。

    完全な 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. Reports.xaml.cs ファイルまたは Reports.xaml.vb ファイルを開きます。

  12. C# の場合は、System.ServiceModel.DomainServices.ClientSystem.ServiceModel.DomainServices.Client.ApplicationServices、および ExampleBusinessApplication.Web の各名前空間の using ステートメントを追加します。Visual Basic の場合は、System.ServiceModel.DomainServices.ClientSystem.ServiceModel.DomainServices.Client.ApplicationServicesSystem.Windows.Controls、および ExampleBusinessApplication.Web の各名前空間の Imports ステートメントを追加します。

  13. context という名前の AdventureWorksDomainContext のインスタンスを作成し、取得する行数を含む numberOfRows という名前の変数を作成します。

    Private context As New AdventureWorksDomainContext
    Private numberOfRows As Integer = 10
    
    private AdventureWorksDomainContext context = new AdventureWorksDomainContext();
    int numberOfRows = 10;
    
  14. ユーザーが Managers ロールに属しており、対応するデータ グリッドに結果を読み込む場合は、GetSalesOrderHeaderQuery メソッドおよび GetCustomersQuery メソッドを呼び出す、LoadRestrictedReports という名前のメソッドを追加します。

    ユーザーが必要な資格情報を持っていない場合にドメイン操作を呼び出すと、ドメイン操作は例外を返します。ドメイン操作を呼び出す前に資格情報を確認することで、この状況を回避できます。

    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. ユーザーが認証されているかどうかを確認し、認証されている場合は LoadRestrictedReports メソッドを呼び出す、LoadReports という名前のメソッドを追加します。また、DefaultRows という名前のプロファイル プロパティを取得し、ユーザー オブジェクトに PropertyChanged イベントのハンドラーを追加します。最後に、すべてのユーザーに対して GetProductsQuery メソッドを呼び出します。

    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. プロパティ DefaultRows が変更された場合に LoadReports を呼び出す PropertyChanged イベントのイベント ハンドラーを追加します。

    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. ユーザー認証の資格情報に対して行われた変更に基づいて、データを読み込むか非表示にする LoggedIn イベントおよび LoggedOut イベントのイベント ハンドラーを追加します。

    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. 次のコードをコンストラクターに追加します。このコードにより、ハンドラーが読み込まれ、LoadReports が呼び出されます。

    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();
    }
    

    完全なコード ファイルを次に示します。

    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. ソリューションを実行します。

  20. [レポート] リンクをクリックします。

    ログインしていない場合、Reports ページには Products テーブルのみが表示されます。

  21. [ログイン] リンクをクリックし、SalesUser としてログインします。

    製品および販売注文に関するテーブルが表示されます。

    RIA_DisplayReports

  22. ログアウトして、CustomerManager としてログインします。

    製品、販売注文、および顧客に関するテーブルが表示されます。

  23. Web ブラウザーを閉じます。

子ウィンドウを追加することで、ユーザーが DefaultRows プロファイル プロパティを編集できるようにすることができます。値を変更した場合は、SaveUser メソッドを呼び出して、値をデータ ソースに保存します。現在の WebContext インスタンスのユーザー オブジェクトのプロパティを使用して、現在の値を取得します。

プロファイル プロパティを設定するためのウィンドウを追加する

  1. クライアント プロジェクトで、Views フォルダーに新しい項目を追加します。

  2. [Silverlight 子ウィンドウ] テンプレートを選択し、子ウィンドウに ProfileWindow.xaml という名前を付けます。

    子ウィンドウの追加

  3. [追加] をクリックします。

  4. ProfileWindow.xaml ファイルで、Grid.RowDefinitions 要素の後に次の XAML を追加し、レポートに表示する行数を選択するための ComboBox を含めます。

    <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. ChildWindowTitle プロパティを Select Preferences に設定します。

  6. ProfileWindow.xaml.cs ファイルまたは ProfileWindow.xaml.vb ファイルで、次のコードを追加して、プロファイル プロパティを取得および設定します。

    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. Visual Basic の場合は、System.Windows.Controls 名前空間および System.Windows 名前空間の Imports ステートメントを追加します。

  8. Views\Login フォルダーを展開し、LoginStatus.xaml ファイルを開きます。

  9. プロファイル ウィンドウに設定リンクを追加するには、ログアウト ボタンの前に次の XAML を追加します。

    <Button x:Name="SettingsButton" Click="SettingsButton_Click" Content="settings" Style="{StaticResource LoginRegisterLinkStyle}" Margin="0,0,0,0"></Button>
    <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
    
  10. LoginStatus.xaml.cs ファイルまたは LoginStatus.xaml.vb ファイルで、設定リンクの次のクリック イベント ハンドラーを追加します。

    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. ソリューションを実行します。

  12. CustomerManager または SalesUser としてログインすると、ログイン ステータス バーに設定のリンクが表示されます。

    RIA_NewLoginStatusBar

  13. [設定] リンクをクリックし、レポートに表示する既定の行数を設定します。

    RIA_ShowProfileSettings

  14. Reports ページを開くと、選択した行数が DataGrid に表示されることがわかります。