Walkthrough: Using Authentication Service with Silverlight Navigation Application
[ This document was written for WCF Services Version 1 Service Pack 2 and might not be up to date Please see Release Notes or Changelog for a list of changes since WCF RIA Services ]
In this walkthrough, you learn how to set up your server and client projects in an Open Ria Services solution to work with an authentication service. When you create a solution with the Silverlight Navigation Application template and enable Open Ria Services, you can access the ASP.NET Membership framework by adding an authentication service. The authentication service exposes authentication, roles, and profiles from the server project to the client project. You use the authentication service to validate user credentials, restrict access to resources based on roles, and store profile properties.
Note: The Silverlight Business Application automatically implements the authentication service. For more information, see Walkthrough: Using Authentication Service with Silverlight Business Application.

Prerequisites

This and the other walkthroughs presented in the Open Ria Services documentation require several prerequisite programs, such as Visual Studio and the Silverlight Developer Runtime and SDK, be installed and configured properly, in addition to Open Ria Services and the Open Ria Services Toolkit. They also require installing and configuring SQL Server 2008 R2 Express with Advanced Services and installing the AdventureWorks OLTP and LT database.
Detailed instructions for the satisfaction of each of these prerequisites are provided by the topics within the Prerequisites for Open Ria Services node. Follow the instructions provided there before proceeding with this walkthrough to ensure that you encounter as few problems as possible when working through this Open Ria Services walkthroughs.

Configuring the Server Project for Authentication, Roles, and Profiles

To use the authentication service from a Silverlight application, you must configure the authentication on the server project. You configure authentication in the Web.config file. After configuring authentication, you can also configure roles and profiles on the server project, if you want to use those features from the Silverlight application. In this walkthrough, you will configure all three features. Finally, you add an authentication service which exposes the enabled features to the client.

To configure the server project

  1. 1.
    In Visual Studio, select File, New, and then Project.
    The New Project dialog box appears.
  2. 2.
    Select the Silverlight project type.
  3. 3.
    Select the Silverlight Navigation Application template and name the application ExampleNavigationApplication.
  4. 4.
    Click OK.
    The New Silverlight Application dialog box appears.
  5. 5.
    Make sure that the Host the Silverlight application in a new Web site check box is selected and that the New Web project type is set to ASP.NET Web Application Project.
  6. 6.
    Select the Enable Open Ria Services check box.
  7. 7.
    Click OK to create the solution.
  8. 8.
    In the server project (ExampleBusinessApplication.Web), open the Web.config file.
  9. 9.
    In the \ element, add an \ element and set the mode property to Forms.
    1
    <authentication mode="Forms"></authentication>
    Copied!
  10. 10.
    In the \ element, add a \ element and set the enabled property to true.
    1
    <roleManager enabled="true"></roleManager>
    Copied!
  11. 11.
    In the \ element, add a \ element, set the enabled property to true, and include a profile property named DefaultRows.
    1
    <profile enabled="true">
    2
    <properties>
    3
    <add type="System.Int32" defaultValue="10" name="DefaultRows"/>
    4
    </properties>
    5
    </profile>
    Copied!
    The completed \ element should include the following elements.
    1
    <system.web>
    2
    <compilation debug="true" targetFramework="4.0" />
    3
    <authentication mode="Forms"></authentication>
    4
    <roleManager enabled="true"></roleManager>
    5
    <profile enabled="true">
    6
    <properties>
    7
    <add type="System.Int32" defaultValue="10" name="DefaultRows"/>
    8
    </properties>
    9
    </profile>
    10
    </system.web>
    Copied!
  12. 12.
    Save the Web.config file.
  13. 13.
    In the Solution Explorer, right-click the server project, select Add and then New Item.
    The Add New Item dialog box appears.
  14. 14.
    Select the Authentication Domain Service template and name it AuthenticationDomainService.
    ​
    ​
  15. 15.
    Click Add.
  16. 16.
    Open the authentication service code file (AuthenticationDomainService.cs or AuthenticationDomainService.vb) and add the DefaultRows property that you defined in the Web.config file to the User class.
    1
    <EnableClientAccess()> _
    2
    Public Class AuthenticationDomainService
    3
    Inherits AuthenticationBase(Of User)
    4
    ​
    5
    End Class
    6
    ​
    7
    Public Class User
    8
    Inherits UserBase
    9
    ​
    10
    Public Property DefaultRows As Integer
    11
    ​
    12
    End Class
    Copied!
    1
    [EnableClientAccess]
    2
    public class AuthenticationDomainService : AuthenticationBase<User>
    3
    {
    4
    }
    5
    ​
    6
    public class User : UserBase
    7
    {
    8
    public int DefaultRows { get; set; }
    9
    }
    Copied!
  17. 17.
    Build the solution.
In this section, you will use the ASP.NET Web Site Administration Tool to create a user and role. You will login as this user in a later section.

To add users with the ASP.NET Web Site Administration Tool

  1. 1.
    To open the ASP.NET Web Site Administration Tool, first select the server project in the Solution Explorer.
  2. 2.
    On the Project menu, select ASP.NET Configuration.
    If you do not see the ASP.NET Configuration option in the Project menu, it may be because you have selected the client project.
    ​
    ​
  3. 3.
    Select the Security tab in ASP.NET Web Site Administration Tool.
    ​
    ​
  4. 4.
    In the Roles section, click the Create or Mange roles link.
  5. 5.
    Add a new role named Managers and click the Add Role button.
    ​
    ​
  6. 6.
    In the lower-right corner, click the Back button.
  7. 7.
    In the Users section, click the Create user link.
  8. 8.
    Create a new user with the following values and select the Managers role check box.
    User Name: CustomerManager
    Security Question: Favorite color?
    Security Answer: Blue
    Managers role: selected
    ​
    ​
  9. 9.
    Click the Create User button.
  10. 10.
    Close the ASP.NET Web Site Administration Tool.

Configuring the Client for Authentication

You must configure the client project to use the authentication mode that matches the authentication mode you configured in the server project.

To configure the client project

  1. 1.
    In the client project, open the code-behind file for the App.xaml file (App.xaml.cs or App.xaml.vb).
  2. 2.
    In the constructor, create a new instance of the WebContext class.
  3. 3.
    Set the Authentication property to a new instance of the FormsAuthentication class, and add the WebContext instance to the ApplicationLifetimeObjects.
    1
    Public Sub New()
    2
    InitializeComponent()
    3
    ​
    4
    Dim webcontext As New WebContext
    5
    webcontext.Authentication = New OpenRiaServices.Client.Authentication.FormsAuthentication
    6
    Me.ApplicationLifetimeObjects.Add(webcontext)
    7
    End Sub
    Copied!
    1
    public App()
    2
    {
    3
    this.Startup += this.Application_Startup;
    4
    this.UnhandledException += this.Application_UnhandledException;
    5
    ​
    6
    InitializeComponent();
    7
    ​
    8
    WebContext webcontext = new WebContext();
    9
    webcontext.Authentication = new OpenRiaServices.Client.Authentication.FormsAuthentication();
    10
    this.ApplicationLifetimeObjects.Add(webcontext);
    11
    }
    Copied!

Adding Login Functionality to the Client

In this section, you will add Silverlight controls that enable the user to provide user name and password for logging in. You will add code that calls the Login method with the user's credentials. You will also set which controls are visible based on whether the user is logged in.
For simplicity, the login user interface is added to the Home page in this walkthrough. In your application, you may want to create a separate login page.

To login and logout a user

  1. 1.
    In Solution Explorer, expand the Views folder in the client project.
  2. 2.
    Open the Home.xaml file.
  3. 3.
    After the TextBlock named ContentText, add the following XAML.
    The XAML includes a TextBox for providing a user name, a PasswordBox for providing a password, a Button for submitting the login request, and a TextBlock and HyperlinkButton for logging out which are only displayed after the user has logged in.
    1
    <TextBlock x:Name="WelcomeText" Style="{StaticResource ContentTextStyle}" Visibility="Collapsed"></TextBlock>
    2
    <HyperlinkButton x:Name="LogoutButton"
    3
    Content="Logout"
    4
    Click="LogoutButton_Click"
    5
    Visibility="Collapsed">
    6
    </HyperlinkButton>
    7
    <Border x:Name="LoginBorder"
    8
    Margin="10,10,0,0"
    9
    BorderThickness="2"
    10
    BorderBrush="Black"
    11
    HorizontalAlignment="Left"
    12
    CornerRadius="15"
    13
    Padding="10"
    14
    Background="BlanchedAlmond"
    15
    Width="300">
    16
    <Grid HorizontalAlignment="Left">
    17
    <Grid.RowDefinitions>
    18
    <RowDefinition></RowDefinition>
    19
    <RowDefinition Height="30" ></RowDefinition>
    20
    <RowDefinition Height="30"></RowDefinition>
    21
    <RowDefinition></RowDefinition>
    22
    <RowDefinition></RowDefinition>
    23
    </Grid.RowDefinitions>
    24
    <Grid.ColumnDefinitions>
    25
    <ColumnDefinition></ColumnDefinition>
    26
    <ColumnDefinition></ColumnDefinition>
    27
    </Grid.ColumnDefinitions>
    28
    <TextBlock Grid.Row="0"
    29
    Grid.ColumnSpan="2"
    30
    Grid.Column="0"
    31
    FontWeight="Bold"
    32
    HorizontalAlignment="Left"
    33
    VerticalAlignment="Center"
    34
    Text="Log In Existing User">
    35
    </TextBlock>
    36
    <TextBlock Grid.Row="1"
    37
    Grid.Column="0"
    38
    HorizontalAlignment="Right"
    39
    VerticalAlignment="Center"
    40
    Text="User Name: ">
    41
    </TextBlock>
    42
    <TextBox x:Name="UserName"
    43
    VerticalAlignment="Center"
    44
    Grid.Row="1"
    45
    Grid.Column="1"
    46
    Width="100">
    47
    </TextBox>
    48
    <TextBlock Grid.Row="2"
    49
    HorizontalAlignment="Right"
    50
    Grid.Column="0"
    51
    VerticalAlignment="Center"
    52
    Text="Password: ">
    53
    </TextBlock>
    54
    <PasswordBox x:Name="Password"
    55
    VerticalAlignment="Center"
    56
    Grid.Row="2"
    57
    Grid.Column="1"
    58
    Width="100">
    59
    </PasswordBox>
    60
    <TextBlock x:Name="LoginResult"
    61
    TextWrapping="Wrap"
    62
    Visibility="Collapsed"
    63
    Grid.Row="3"
    64
    Grid.ColumnSpan="2"
    65
    Foreground="Red">
    66
    </TextBlock>
    67
    <Button x:Name="LoginButton"
    68
    Margin="0,5,0,0"
    69
    Grid.Row="4"
    70
    Grid.Column="1"
    71
    Content="Log In"
    72
    Click="LoginButton_Click">
    73
    </Button>
    74
    </Grid>
    75
    </Border>
    Copied!
  4. 4.
    Open the code-behind file for the home page (Home.xaml.cs or Home.xaml.vb).
  5. 5.
    Add a using or an Imports statement for the OpenRiaServices.Client.Authentication namespace.
  6. 6.
    Add the following code to the Home class.
    The code includes event handlers for logging in and logging out, callback methods for completed login and logout operations, and a method that set the visibility of controls based on whether the user is authenticated.
    1
    Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    2
    SetControlVisibility(WebContext.Current.User.IsAuthenticated)
    3
    End Sub
    4
    ​
    5
    Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    6
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    7
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    8
    LoginButton.IsEnabled = False
    9
    LoginResult.Text = ""
    10
    End Sub
    11
    ​
    12
    Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    13
    If (lo.HasError) Then
    14
    LoginResult.Text = lo.Error.Message
    15
    LoginResult.Visibility = System.Windows.Visibility.Visible
    16
    lo.MarkErrorAsHandled()
    17
    ElseIf (lo.LoginSuccess = False) Then
    18
    LoginResult.Text = "Login failed. Please check user name and password."
    19
    LoginResult.Visibility = System.Windows.Visibility.Visible
    20
    ElseIf (lo.LoginSuccess = True) Then
    21
    SetControlVisibility(True)
    22
    End If
    23
    LoginButton.IsEnabled = True
    24
    End Sub
    25
    ​
    26
    Private Sub SetControlVisibility(ByVal isAuthenticated As Boolean)
    27
    If (isAuthenticated) Then
    28
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed
    29
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name
    30
    WelcomeText.Visibility = System.Windows.Visibility.Visible
    31
    LogoutButton.Visibility = System.Windows.Visibility.Visible
    32
    Else
    33
    LoginBorder.Visibility = System.Windows.Visibility.Visible
    34
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed
    35
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed
    36
    End If
    37
    End Sub
    38
    ​
    39
    Private Sub LogoutButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    40
    WebContext.Current.Authentication.Logout(AddressOf Me.LogoutOperation_Completed, Nothing)
    41
    End Sub
    42
    ​
    43
    Private Sub LogoutOperation_Completed(ByVal lo As LogoutOperation)
    44
    If (Not (lo.HasError)) Then
    45
    SetControlVisibility(False)
    46
    Else
    47
    Dim ew As ErrorWindow = New ErrorWindow("Logout failed.", "Please try logging out again.")
    48
    ew.Show()
    49
    lo.MarkErrorAsHandled()
    50
    End If
    51
    End Sub
    Copied!
    1
    protected override void OnNavigatedTo(NavigationEventArgs e)
    2
    {
    3
    SetControlVisibility(WebContext.Current.User.IsAuthenticated);
    4
    }
    5
    ​
    6
    private void LoginButton_Click(object sender, RoutedEventArgs e)
    7
    {
    8
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    9
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    10
    LoginButton.IsEnabled = false;
    11
    LoginResult.Text = "";
    12
    }
    13
    ​
    14
    private void LoginOperation_Completed(LoginOperation lo)
    15
    {
    16
    if (lo.HasError)
    17
    {
    18
    LoginResult.Text = lo.Error.Message;
    19
    LoginResult.Visibility = System.Windows.Visibility.Visible;
    20
    lo.MarkErrorAsHandled();
    21
    }
    22
    else if (lo.LoginSuccess == false)
    23
    {
    24
    LoginResult.Text = "Login failed. Please check user name and password.";
    25
    LoginResult.Visibility = System.Windows.Visibility.Visible;
    26
    }
    27
    else if (lo.LoginSuccess == true)
    28
    {
    29
    SetControlVisibility(true);
    30
    }
    31
    LoginButton.IsEnabled = true;
    32
    }
    33
    ​
    34
    private void SetControlVisibility(bool isAuthenticated)
    35
    {
    36
    if (isAuthenticated)
    37
    {
    38
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed;
    39
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name;
    40
    WelcomeText.Visibility = System.Windows.Visibility.Visible;
    41
    LogoutButton.Visibility = System.Windows.Visibility.Visible;
    42
    }
    43
    else
    44
    {
    45
    LoginBorder.Visibility = System.Windows.Visibility.Visible;
    46
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed;
    47
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed;
    48
    }
    49
    }
    50
    ​
    51
    private void LogoutButton_Click(object sender, RoutedEventArgs e)
    52
    {
    53
    WebContext.Current.Authentication.Logout(this.LogoutOperation_Completed, null);
    54
    }
    55
    ​
    56
    private void LogoutOperation_Completed(LogoutOperation lo)
    57
    {
    58
    ​
    59
    if (!lo.HasError)
    60
    {
    61
    SetControlVisibility(false);
    62
    }
    63
    else
    64
    {
    65
    ErrorWindow ew = new ErrorWindow("Logout failed.", "Please try logging out again.");
    66
    ew.Show();
    67
    lo.MarkErrorAsHandled();
    68
    }
    69
    }
    Copied!
  7. 7.
    Run the solution.
    ​
    ​
  8. 8.
    Log in as CustomerManager with [email protected] for the password.
    Notice that the Login area is no longer displayed, but the welcome text and logout link are now displayed.
    ​
    ​
  9. 9.
    Click Logout link and close Web browser.

Adding New Users from the Client

The authentication service does not contain an operation to create new users. To register a new user, you create an empty domain service and add an operation for adding a user to the ASP.NET Membership framework.

To configure the server project for adding a new user

  1. 1.
    In the server project, add a new class file named NewUser.
  2. 2.
    Define the properties for registering a new user by adding the following code to the NewUser class.
    1
    Imports System.ComponentModel.DataAnnotations
    2
    ​
    3
    Public Class NewUser
    4
    ​
    5
    <Key()> _
    6
    <Required()> _
    7
    <RegularExpression("^[a-zA-Z0-9_]*quot;, ErrorMessage:="Invalid user name. It must contain only alphanumeric characters")> _
    8
    Public Property UserName As String
    9
    ​
    10
    <Key()> _
    11
    <Required()> _
    12
    <RegularExpression("^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)quot;, ErrorMessage:="Invalid email. An email must use the format [email protected]")> _
    13
    Public Property Email As String
    14
    ​
    15
    <Required()> _
    16
    <RegularExpression("^.*[^a-zA-Z0-9].*quot;, ErrorMessage:="A password needs to contain at least one special character e.g. @ or #")> _
    17
    <StringLength(50, MinimumLength:=7, ErrorMessage:="Invalid password. It must be contain at least 7 characters and no more than 50 characters.")> _
    18
    Public Property Password As String
    19
    ​
    20
    <Required()> _
    21
    <CustomValidation(GetType(RegistrationValidator), "IsPasswordConfirmed")> _
    22
    Public Property ConfirmPassword As String
    23
    ​
    24
    <Range(1, 20)> _
    25
    Public Property RecordsToShow As Integer
    26
    ​
    27
    <Required()> _
    28
    Public Property SecurityQuestion As String
    29
    ​
    30
    <Required()> _
    31
    Public Property SecurityAnswer As String
    32
    End Class
    Copied!
    1
    using System;
    2
    using System.ComponentModel.DataAnnotations;
    3
    ​
    4
    namespace ExampleNavigationApplication.Web
    5
    {
    6
    public class NewUser
    7
    {
    8
    [Key]
    9
    [Required()]
    10
    [RegularExpression("^[a-zA-Z0-9_]*quot;, ErrorMessage="Invalid user name. It must contain only alphanumeric characters")]
    11
    public string UserName { get; set; }
    12
    ​
    13
    [Key]
    14
    [Required()]
    15
    [RegularExpression(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)quot;, ErrorMessage="Invalid email. An email must use the format [email protected]")]
    16
    public string Email { get; set; }
    17
    ​
    18
    [Required()]
    19
    [RegularExpression("^.*[^a-zA-Z0-9].*quot;, ErrorMessage="A password needs to contain at least one special character e.g. @ or #")]
    20
    [StringLength(50, MinimumLength = 7, ErrorMessage="Invalid password. It must be contain at least 7 characters and no more than 50 characters.")]
    21
    public string Password { get; set; }
    22
    ​
    23
    [Required()]
    24
    [CustomValidation(typeof(RegistrationValidator), "IsPasswordConfirmed")]
    25
    public string ConfirmPassword { get; set; }
    26
    ​
    27
    [Range(1, 20)]
    28
    public int RecordsToShow { get; set; }
    29
    ​
    30
    [Required()]
    31
    public string SecurityQuestion { get; set; }
    32
    ​
    33
    [Required()]
    34
    public string SecurityAnswer { get; set; }
    35
    }
    36
    }
    Copied!
    The ConfirmPassword property in the previous step is defined with a CustomValidationAttribute attribute. In the attribute, it specifies a RegistrationValidator class and a method named IsPasswordConfirmed. You must now define this custom validation class.
  3. 3.
    Add a new class named RegistrationValidator.shared.cs or RegistrationValidator.shared.vb.
  4. 4.
    Add the following code to the RegistrationValidator.shared file.
    1
    Imports System.ComponentModel.DataAnnotations
    2
    ​
    3
    Public Class RegistrationValidator
    4
    Public Shared Function IsPasswordConfirmed(ByVal confirmPassword As String, ByVal context As ValidationContext) As ValidationResult
    5
    Dim data As Web.NewUser = CType(context.ObjectInstance, Web.NewUser)
    6
    If (data.Password = confirmPassword) Then
    7
    Return ValidationResult.Success
    8
    Else
    9
    Return New ValidationResult("Please confirm your password by providing it again.")
    10
    End If
    11
    End Function
    12
    End Class
    Copied!
    1
    using System.ComponentModel.DataAnnotations;
    2
    ​
    3
    namespace ExampleNavigationApplication.Web
    4
    {
    5
    public class RegistrationValidator
    6
    {
    7
    public static ValidationResult IsPasswordConfirmed(string confirmPassword, ValidationContext context)
    8
    {
    9
    NewUser data = (NewUser)context.ObjectInstance;
    10
    if (data.Password == confirmPassword)
    11
    {
    12
    return ValidationResult.Success;
    13
    }
    14
    else
    15
    {
    16
    return new ValidationResult("Please confirm your password by providing it again.");
    17
    }
    18
    }
    19
    }
    20
    }
    Copied!
  5. 5.
    Add a new item to the server project and select the Domain Service Class template.
  6. 6.
    Name the file RegistrationDomainService.cs or RegistrationDomainService.vb and then click the Add button.
  7. 7.
    In the Add New Domain Service Class dialog box, select \ from the Available DataContexts/ObjectContexts list.
  8. 8.
    Click OK.
  9. 9.
    To create a domain operation that adds a new user through the Membership framework and saves a profile property, add the following code to the RegistrationDomainService class.
    The GetUsers method must be included to ensure that the NewUser entity class is generated for the client project. Only classes that are exposed through a public query operation are generated in the client project.
    After creating the user, the profile property named DefaultRows is set. In this case, the profile property is set as part of the domain operation for creating a user. In a later section, you will add code to set the profile property from the client project.
    1
    Option Compare Binary
    2
    Option Infer On
    3
    Option Strict On
    4
    Option Explicit On
    5
    ​
    6
    Imports System
    7
    Imports System.Collections.Generic
    8
    Imports System.ComponentModel
    9
    Imports System.ComponentModel.DataAnnotations
    10
    Imports System.Linq
    11
    Imports OpenRiaServices.Hosting
    12
    Imports OpenRiaServices.Server
    13
    Imports System.Web.Profile
    14
    ​
    15
    <EnableClientAccess()> _
    16
    Public Class RegistrationDomainService
    17
    Inherits DomainService
    18
    ​
    19
    Public Sub AddUser(ByVal user As NewUser)
    20
    Dim createStatus As MembershipCreateStatus
    21
    Membership.CreateUser(user.UserName, user.Password, user.Email, user.SecurityQuestion, user.SecurityAnswer, True, Nothing, createStatus)
    22
    ​
    23
    If (createStatus <> MembershipCreateStatus.Success) Then
    24
    Throw New DomainException(createStatus.ToString())
    25
    End If
    26
    ​
    27
    Dim profile = ProfileBase.Create(user.UserName, True)
    28
    profile.SetPropertyValue("DefaultRows", user.RecordsToShow)
    29
    profile.Save()
    30
    End Sub
    31
    ​
    32
    Public Function GetUsers() As IEnumerable(Of NewUser)
    33
    Throw New NotSupportedException()
    34
    End Function
    35
    End Class
    Copied!
    ``` csharp namespace ExampleNavigationApplication.Web { using System; using System.Collections.Generic; using OpenRiaServices.Hosting; using OpenRiaServices.Server; using System.Web.Security; using System.Web.Profile;
1
[EnableClientAccess()]
2
public class RegistrationDomainService : DomainService
3
{
4
public void AddUser(NewUser user)
5
{
6
MembershipCreateStatus createStatus;
7
Membership.CreateUser(user.UserName, user.Password, user.Email, user.SecurityQuestion, user.SecurityAnswer, true, null, out createStatus);
8
​
9
if (createStatus != MembershipCreateStatus.Success)
10
{
11
throw new DomainException(createStatus.ToString());
12
}
13
​
14
ProfileBase profile = ProfileBase.Create(user.UserName, true);
15
profile.SetPropertyValue("DefaultRows", user.RecordsToShow);
16
profile.Save();
17
}
18
​
19
public IEnumerable<NewUser> GetUsers()
20
{
21
throw new NotSupportedException();
22
}
23
}
24
}
25
```
Copied!

To configure the client project for adding new users

  1. 1.
    Open the Home.xaml file.
  2. 2.
    After the end tag for the LoginBorderBorder control, add the following XAML to create a second Border control with input controls to collect information for creating new users.
    The controls accept values for user name, password, password confirmation, e-mail address, security question, security answer, and the number of records to show on reports. The number of records to display will be saved as a profile property. All of the other values are used to create the user through ASP.NET Membership framework.
    1
    <Border x:Name="RegisterBorder"
    2
    Margin="10,10,0,0"
    3
    BorderThickness="2"
    4
    BorderBrush="Black"
    5
    HorizontalAlignment="Left"
    6
    CornerRadius="15"
    7
    Padding="10"
    8
    Background="BurlyWood"
    9
    Width="400">
    10
    <Grid HorizontalAlignment="Left">
    11
    <Grid.RowDefinitions>
    12
    <RowDefinition></RowDefinition>
    13
    <RowDefinition Height="30" ></RowDefinition>
    14
    <RowDefinition Height="30"></RowDefinition>
    15
    <RowDefinition Height="30"></RowDefinition>
    16
    <RowDefinition Height="30"></RowDefinition>
    17
    <RowDefinition Height="30"></RowDefinition>
    18
    <RowDefinition Height="30"></RowDefinition>
    19
    <RowDefinition Height="30"></RowDefinition>
    20
    <RowDefinition></RowDefinition>
    21
    <RowDefinition></RowDefinition>
    22
    </Grid.RowDefinitions>
    23
    <Grid.ColumnDefinitions>
    24
    <ColumnDefinition></ColumnDefinition>
    25
    <ColumnDefinition></ColumnDefinition>
    26
    </Grid.ColumnDefinitions>
    27
    ​
    28
    <TextBlock Grid.Row="0"
    29
    Grid.ColumnSpan="2"
    30
    Grid.Column="0"
    31
    FontWeight="Bold"
    32
    HorizontalAlignment="Left"
    33
    VerticalAlignment="Center"
    34
    Text="Register New User">
    35
    </TextBlock>
    36
    <TextBlock Grid.Row="1"
    37
    Grid.Column="0"
    38
    HorizontalAlignment="Right"
    39
    VerticalAlignment="Center"
    40
    Text="User Name: ">
    41
    </TextBlock>
    42
    <TextBox x:Name="NewUsername"
    43
    VerticalAlignment="Center"
    44
    HorizontalAlignment="Left"
    45
    Grid.Row="1"
    46
    Grid.Column="1"
    47
    Width="100">
    48
    </TextBox>
    49
    <TextBlock Grid.Row="2"
    50
    HorizontalAlignment="Right"
    51
    Grid.Column="0"
    52
    VerticalAlignment="Center"
    53
    Text="Password: ">
    54
    </TextBlock>
    55
    <PasswordBox x:Name="NewPassword"
    56
    VerticalAlignment="Center"
    57
    HorizontalAlignment="Left"
    58
    Grid.Row="2"
    59
    Grid.Column="1"
    60
    Width="100">
    61
    </PasswordBox>
    62
    <TextBlock Grid.Row="3"
    63
    HorizontalAlignment="Right"
    64
    Grid.Column="0"
    65
    VerticalAlignment="Center"
    66
    Text="Confirm Password: ">
    67
    </TextBlock>
    68
    <PasswordBox x:Name="NewConfirmPassword"
    69
    HorizontalAlignment="Left"
    70
    VerticalAlignment="Center"
    71
    Grid.Row="3"
    72
    Grid.Column="1"
    73
    Width="100">
    74
    </PasswordBox>
    75
    <TextBlock Grid.Row="4"
    76
    HorizontalAlignment="Right"
    77
    Grid.Column="0"
    78
    VerticalAlignment="Center"
    79
    Text="Email: ">
    80
    </TextBlock>
    81
    <TextBox x:Name="NewEmail"
    82
    VerticalAlignment="Center"
    83
    Grid.Row="4"
    84
    Grid.Column="1"
    85
    Width="200">
    86
    </TextBox>
    87
    <TextBlock Grid.Row="5"
    88
    HorizontalAlignment="Right"
    89
    Grid.Column="0"
    90
    VerticalAlignment="Center"
    91
    Text="Records to show: ">
    92
    </TextBlock>
    93
    <ComboBox Grid.Row="5"
    94
    Grid.Column="1"
    95
    x:Name="DefaultRows"
    96
    HorizontalAlignment="Left"
    97
    Width="50"
    98
    Height="20"
    99
    VerticalAlignment="Center">
    100
    <ComboBoxItem Content="1"></ComboBoxItem>
    101
    <ComboBoxItem Content="3"></ComboBoxItem>
    102
    <ComboBoxItem Content="5"></ComboBoxItem>
    103
    <ComboBoxItem Content="10" IsSelected="True"></ComboBoxItem>
    104
    <ComboBoxItem Content="15"></ComboBoxItem>
    105
    <ComboBoxItem Content="20"></ComboBoxItem>
    106
    </ComboBox>
    107
    <TextBlock Grid.Row="6"
    108
    HorizontalAlignment="Right"
    109
    Grid.Column="0"
    110
    VerticalAlignment="Center"
    111
    Text="Security Question: ">
    112
    </TextBlock>
    113
    <TextBox x:Name="SecurityQuestion"
    114
    VerticalAlignment="Center"
    115
    Grid.Row="6"
    116
    Grid.Column="1"
    117
    Width="200">
    118
    </TextBox>
    119
    <TextBlock Grid.Row="7"
    120
    HorizontalAlignment="Right"
    121
    Grid.Column="0"
    122
    VerticalAlignment="Center"
    123
    Text="Security Answer: ">
    124
    </TextBlock>
    125
    <TextBox x:Name="SecurityAnswer"
    126
    VerticalAlignment="Center"
    127
    Grid.Row="7"
    128
    Grid.Column="1"
    129
    Width="200">
    130
    </TextBox>
    131
    <TextBlock x:Name="registerResult"
    132
    TextWrapping="Wrap"
    133
    Visibility="Collapsed"
    134
    Grid.Row="8"
    135
    Grid.ColumnSpan="2"
    136
    Foreground="Red">
    137
    </TextBlock>
    138
    <Button x:Name="RegisterButton"
    139
    Click="RegisterButton_Click"
    140
    Margin="0,5,0,0"
    141
    Grid.Row="9"
    142
    Grid.Column="1"
    143
    Content="Register" >
    144
    </Button>
    145
    </Grid>
    146
    </Border>
    Copied!
  3. 3.
    Open the Home.xaml.cs (or Home.xaml.vb) code-behind file.
  4. 4.
    Add a using or an Imports statement for the OpenRiaServices.Client, System.ComponentModel.DataAnnotations, and ExampleNavigationApplication.Web namespaces.
  5. 5.
    Add an event handler for the register button click event and add a callback method for domain operation. The callback method includes code to login the user after successfully creating the user account.
    1
    Private Sub RegisterButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    2
    RegisterButton.IsEnabled = False
    3
    Dim context = New RegistrationDomainContext()
    4
    Dim nu = New NewUser()
    5
    Try
    6
    nu.UserName = NewUsername.Text
    7
    nu.Password = NewPassword.Password
    8
    nu.Email = NewEmail.Text
    9
    nu.ConfirmPassword = NewConfirmPassword.Password
    10
    nu.RecordsToShow = Integer.Parse(DefaultRows.SelectionBoxItem.ToString())
    11
    nu.SecurityQuestion = SecurityQuestion.Text
    12
    nu.SecurityAnswer = SecurityAnswer.Text
    13
    context.NewUsers.Add(nu)
    14
    ​
    15
    context.SubmitChanges(AddressOf RegisterUser_Completed, Nothing)
    16
    Catch ve As ValidationException
    17
    registerResult.Visibility = System.Windows.Visibility.Visible
    18
    registerResult.Text = ve.Message
    19
    RegisterButton.IsEnabled = True
    20
    End Try
    21
    End Sub
    22
    ​
    23
    Private Sub RegisterUser_Completed(ByVal so As SubmitOperation)
    24
    If (so.HasError) Then
    25
    Dim ew = New ErrorWindow("Registration failed.", "Please try registering again.")
    26
    ew.Show()
    27
    so.MarkErrorAsHandled()
    28
    Else
    29
    Dim lp = New LoginParameters(NewUsername.Text, NewPassword.Password)
    30
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    31
    NewUsername.Text = ""
    32
    NewPassword.Password = ""
    33
    NewConfirmPassword.Password = ""
    34
    NewEmail.Text = ""
    35
    DefaultRows.SelectedIndex = 0
    36
    SecurityQuestion.Text = ""
    37
    SecurityAnswer.Text = ""
    38
    End If
    39
    RegisterButton.IsEnabled = True
    40
    End Sub
    Copied!
    1
    private void RegisterButton_Click(object sender, RoutedEventArgs e)
    2
    {
    3
    RegisterButton.IsEnabled = false;
    4
    RegistrationDomainContext context = new RegistrationDomainContext();
    5
    NewUser nu = new NewUser();
    6
    try
    7
    {
    8
    nu.UserName = NewUsername.Text;
    9
    nu.Password = NewPassword.Password;
    10
    nu.Email = NewEmail.Text;
    11
    nu.ConfirmPassword = NewConfirmPassword.Password;
    12
    nu.RecordsToShow = int.Parse(DefaultRows.SelectionBoxItem.ToString());
    13
    nu.SecurityQuestion = SecurityQuestion.Text;
    14
    nu.SecurityAnswer = SecurityAnswer.Text;
    15
    context.NewUsers.Add(nu);
    16
    ​
    17
    context.SubmitChanges(RegisterUser_Completed, null);
    18
    }
    19
    catch (ValidationException ve)
    20
    {
    21
    registerResult.Visibility = System.Windows.Visibility.Visible;
    22
    registerResult.Text = ve.Message;
    23
    RegisterButton.IsEnabled = true;
    24
    }
    25
    }
    26
    ​
    27
    private void RegisterUser_Completed(SubmitOperation so)
    28
    {
    29
    if (so.HasError)
    30
    {
    31
    ErrorWindow ew = new ErrorWindow("Registration failed.", "Please try registering again.");
    32
    ew.Show();
    33
    so.MarkErrorAsHandled();
    34
    }
    35
    else
    36
    {
    37
    LoginParameters lp = new LoginParameters(NewUsername.Text, NewPassword.Password);
    38
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    39
    NewUsername.Text = "";
    40
    NewPassword.Password = "";
    41
    NewConfirmPassword.Password = "";
    42
    NewEmail.Text = "";
    43
    DefaultRows.SelectedIndex = 0;
    44
    SecurityQuestion.Text = "";
    45
    SecurityAnswer.Text = "";
    46
    }
    47
    RegisterButton.IsEnabled = true;
    48
    }
    Copied!
  6. 6.
    Modify the SetControlVisibility method to set the visibility of RegisterBorder, as shown in the following code.
    1
    Private Sub SetControlVisibility(ByVal isAuthenticated As Boolean)
    2
    If (isAuthenticated) Then
    3
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed
    4
    RegisterBorder.Visibility = Windows.Visibility.Collapsed
    5
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name
    6
    WelcomeText.Visibility = System.Windows.Visibility.Visible
    7
    LogoutButton.Visibility = System.Windows.Visibility.Visible
    8
    Else
    9
    LoginBorder.Visibility = System.Windows.Visibility.Visible
    10
    RegisterBorder.Visibility = Windows.Visibility.Visible
    11
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed
    12
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed
    13
    End If
    14
    End Sub
    Copied!
    1
    private void SetControlVisibility(bool isAuthenticated)
    2
    {
    3
    if (isAuthenticated)
    4
    {
    5
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed;
    6
    RegisterBorder.Visibility = System.Windows.Visibility.Collapsed;
    7
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name;
    8
    WelcomeText.Visibility = System.Windows.Visibility.Visible;
    9
    LogoutButton.Visibility = System.Windows.Visibility.Visible;
    10
    }
    11
    else
    12
    {
    13
    LoginBorder.Visibility = System.Windows.Visibility.Visible;
    14
    RegisterBorder.Visibility = System.Windows.Visibility.Visible;
    15
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed;
    16
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed;
    17
    }
    18
    }
    Copied!
    The following shows the complete code-behind file.
    1
    Imports OpenRiaServices.Client.Authentication
    2
    Imports OpenRiaServices.Client
    3
    Imports System.ComponentModel.DataAnnotations
    4
    ​
    5
    Partial Public Class Home
    6
    Inherits Page
    7
    ​
    8
    Public Sub New()
    9
    InitializeComponent()
    10
    End Sub
    11
    ​
    12
    Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    13
    SetControlVisibility(WebContext.Current.User.IsAuthenticated)
    14
    End Sub
    15
    ​
    16
    Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    17
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    18
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    19
    LoginButton.IsEnabled = False
    20
    LoginResult.Text = ""
    21
    End Sub
    22
    ​
    23
    Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    24
    If (lo.HasError) Then
    25
    LoginResult.Text = lo.Error.Message
    26
    LoginResult.Visibility = System.Windows.Visibility.Visible
    27
    lo.MarkErrorAsHandled()
    28
    ElseIf (lo.LoginSuccess = False) Then
    29
    LoginResult.Text = "Login failed. Please check user name and password."
    30
    LoginResult.Visibility = System.Windows.Visibility.Visible
    31
    ElseIf (lo.LoginSuccess = True) Then
    32
    SetControlVisibility(True)
    33
    End If
    34
    LoginButton.IsEnabled = True
    35
    End Sub
    36
    ​
    37
    Private Sub SetControlVisibility(ByVal isAuthenticated As Boolean)
    38
    If (isAuthenticated) Then
    39
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed
    40
    RegisterBorder.Visibility = Windows.Visibility.Collapsed
    41
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name
    42
    WelcomeText.Visibility = System.Windows.Visibility.Visible
    43
    LogoutButton.Visibility = System.Windows.Visibility.Visible
    44
    Else
    45
    LoginBorder.Visibility = System.Windows.Visibility.Visible
    46
    RegisterBorder.Visibility = Windows.Visibility.Visible
    47
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed
    48
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed
    49
    End If
    50
    End Sub
    51
    ​
    52
    Private Sub LogoutButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    53
    WebContext.Current.Authentication.Logout(AddressOf Me.LogoutOperation_Completed, Nothing)
    54
    End Sub
    55
    ​
    56
    Private Sub LogoutOperation_Completed(ByVal lo As LogoutOperation)
    57
    If (Not (lo.HasError)) Then
    58
    SetControlVisibility(False)
    59
    Else
    60
    Dim ew As ErrorWindow = New ErrorWindow("Logout failed.", "Please try logging out again.")
    61
    ew.Show()
    62
    lo.MarkErrorAsHandled()
    63
    End If
    64
    End Sub
    65
    ​
    66
    Private Sub RegisterButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    67
    RegisterButton.IsEnabled = False
    68
    Dim context = New RegistrationDomainContext()
    69
    Dim nu = New NewUser()
    70
    Try
    71
    nu.UserName = NewUsername.Text
    72
    nu.Password = NewPassword.Password
    73
    nu.Email = NewEmail.Text
    74
    nu.ConfirmPassword = NewConfirmPassword.Password
    75
    nu.RecordsToShow = Integer.Parse(DefaultRows.SelectionBoxItem.ToString())
    76
    nu.SecurityQuestion = SecurityQuestion.Text
    77
    nu.SecurityAnswer = SecurityAnswer.Text
    78
    context.NewUsers.Add(nu)
    79
    ​
    80
    context.SubmitChanges(AddressOf RegisterUser_Completed, Nothing)
    81
    Catch ve As ValidationException
    82
    registerResult.Visibility = System.Windows.Visibility.Visible
    83
    registerResult.Text = ve.Message
    84
    RegisterButton.IsEnabled = True
    85
    End Try
    86
    End Sub
    87
    ​
    88
    Private Sub RegisterUser_Completed(ByVal so As SubmitOperation)
    89
    If (so.HasError) Then
    90
    Dim ew = New ErrorWindow("Registration failed.", "Please try registering again.")
    91
    ew.Show()
    92
    so.MarkErrorAsHandled()
    93
    Else
    94
    Dim lp = New LoginParameters(NewUsername.Text, NewPassword.Password)
    95
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    96
    NewUsername.Text = ""
    97
    NewPassword.Password = ""
    98
    NewConfirmPassword.Password = ""
    99
    NewEmail.Text = ""
    100
    DefaultRows.SelectedIndex = 0
    101
    SecurityQuestion.Text = ""
    102
    SecurityAnswer.Text = ""
    103
    End If
    104
    RegisterButton.IsEnabled = True
    105
    End Sub
    106
    End Class
    Copied!
    1
    using System;
    2
    using System.Windows;
    3
    using System.Windows.Controls;
    4
    using System.Windows.Navigation;
    5
    using OpenRiaServices.Client.Authentication;
    6
    using OpenRiaServices.Client;
    7
    using System.ComponentModel.DataAnnotations;
    8
    using ExampleNavigationApplication.Web;
    9
    ​
    10
    namespace ExampleNavigationApplication
    11
    {
    12
    public partial class Home : Page
    13
    {
    14
    public Home()
    15
    {
    16
    InitializeComponent();
    17
    ​
    18
    }
    19
    ​
    20
    // Executes when the user navigates to this page.
    21
    protected override void OnNavigatedTo(NavigationEventArgs e)
    22
    {
    23
    SetControlVisibility(WebContext.Current.User.IsAuthenticated);
    24
    }
    25
    ​
    26
    private void LoginButton_Click(object sender, RoutedEventArgs e)
    27
    {
    28
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    29
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    30
    LoginButton.IsEnabled = false;
    31
    LoginResult.Text = "";
    32
    }
    33
    ​
    34
    private void LoginOperation_Completed(LoginOperation lo)
    35
    {
    36
    if (lo.HasError)
    37
    {
    38
    LoginResult.Text = lo.Error.Message;
    39
    LoginResult.Visibility = System.Windows.Visibility.Visible;
    40
    lo.MarkErrorAsHandled();
    41
    }
    42
    else if (lo.LoginSuccess == false)
    43
    {
    44
    LoginResult.Text = "Login failed. Please check user name and password.";
    45
    LoginResult.Visibility = System.Windows.Visibility.Visible;
    46
    }
    47
    else if (lo.LoginSuccess == true)
    48
    {
    49
    SetControlVisibility(true);
    50
    }
    51
    LoginButton.IsEnabled = true;
    52
    }
    53
    ​
    54
    private void SetControlVisibility(bool isAuthenticated)
    55
    {
    56
    if (isAuthenticated)
    57
    {
    58
    LoginBorder.Visibility = System.Windows.Visibility.Collapsed;
    59
    RegisterBorder.Visibility = System.Windows.Visibility.Collapsed;
    60
    WelcomeText.Text = "Welcome " + WebContext.Current.User.Name;
    61
    WelcomeText.Visibility = System.Windows.Visibility.Visible;
    62
    LogoutButton.Visibility = System.Windows.Visibility.Visible;
    63
    }
    64
    else
    65
    {
    66
    LoginBorder.Visibility = System.Windows.Visibility.Visible;
    67
    RegisterBorder.Visibility = System.Windows.Visibility.Visible;
    68
    WelcomeText.Visibility = System.Windows.Visibility.Collapsed;
    69
    LogoutButton.Visibility = System.Windows.Visibility.Collapsed;
    70
    }
    71
    }
    72
    ​
    73
    private void LogoutButton_Click(object sender, RoutedEventArgs e)
    74
    {
    75
    WebContext.Current.Authentication.Logout(this.LogoutOperation_Completed, null);
    76
    }
    77
    ​
    78
    private void LogoutOperation_Completed(LogoutOperation lo)
    79
    {
    80
    ​
    81
    if (!lo.HasError)
    82
    {
    83
    SetControlVisibility(false);
    84
    }
    85
    else
    86
    {
    87
    ErrorWindow ew = new ErrorWindow("Logout failed.", "Please try logging out again.");
    88
    ew.Show();
    89
    lo.MarkErrorAsHandled();
    90
    }
    91
    }
    92
    ​
    93
    private void RegisterButton_Click(object sender, RoutedEventArgs e)
    94
    {
    95
    RegisterButton.IsEnabled = false;
    96
    RegistrationDomainContext context = new RegistrationDomainContext();
    97
    NewUser nu = new NewUser();
    98
    try
    99
    {
    100
    nu.UserName = NewUsername.Text;
    101
    nu.Password = NewPassword.Password;
    102
    nu.Email = NewEmail.Text;
    103
    nu.ConfirmPassword = NewConfirmPassword.Password;
    104
    nu.RecordsToShow = int.Parse(DefaultRows.SelectionBoxItem.ToString());
    105
    nu.SecurityQuestion = SecurityQuestion.Text;
    106
    nu.SecurityAnswer = SecurityAnswer.Text;
    107
    context.NewUsers.Add(nu);
    108
    ​
    109
    context.SubmitChanges(RegisterUser_Completed, null);
    110
    }
    111
    catch (ValidationException ve)
    112
    {
    113
    registerResult.Visibility = System.Windows.Visibility.Visible;
    114
    registerResult.Text = ve.Message;
    115
    RegisterButton.IsEnabled = true;
    116
    }
    117
    }
    118
    ​
    119
    private void RegisterUser_Completed(SubmitOperation so)
    120
    {
    121
    if (so.HasError)
    122
    {
    123
    ErrorWindow ew = new ErrorWindow("Registration failed.", "Please try registering again.");
    124
    ew.Show();
    125
    so.MarkErrorAsHandled();
    126
    }
    127
    else
    128
    {
    129
    LoginParameters lp = new LoginParameters(NewUsername.Text, NewPassword.Password);
    130
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);<