Adding User Management to your business application

RIA “Business application” template adds login screen and logic to use Membership and role management.You just need to alter your web.cofig and create aspnet database.The configuration has already been cover in previous articles. In this article i will create Userdata metatdata class (for MembershipUser) and display all users in the system in DataGrid.User can also update some flags like IsApproved and IsLocked from this screen.User can also select single or multiple users from grid and click on delete to delete users from Membership. Users is not allowed to use IsLocked flag to lock account however he can use this checkbox to unlock the locked accounts.In this article we will learn how we can bind data grid to our custom entity,Update the data on web service when ever user changes anything in client side.Add custom validation to ensure that user is allowed to set IsLocked=false; and is not allowed to set IsLocked = true;

1. To your web project add class UserData to Modles which will be used hold metadata for MembershipUser.

public class UserData
{  [Display(Order = 1, Name = "User Name")]
    [Key]
    public string UserName { get; set; }
    [ReadOnly(true)]
    [Display(Order = 2, Name = "Email")]
    public string Email { get; set; }
    [ReadOnly(true)]
    [Display(Order = 3, Name = "Created On")]
    public DateTime CreationDate { get; set; }
    [ReadOnly(true)]
    [Display(Order = 4, Name = "Last Login")]
    public DateTime LastLoginDate { get; set; }
    [ReadOnly(true)]
    [Display(Order = 5, Name = "Is Online")]
    public bool IsOnline { get; set; }
    [Display(Order = 6, Name = "Is Approved")]
    [Editable(true)]
    public bool IsApproved { get; set; }
    [Display(Order = 7, Name = "Is Locked")]
    [Editable(true)]
    [CustomValidation(typeof(Shared.Security.IsLockedOutValidator), "IsLockedOutValidValue")]
    public bool IsLockedOut { get; set; }
    [ReadOnly(true)]
    [Display(Order = 8, Name = "Last Lockout")]
    public DateTime LastLockoutDate
    {
        get;
        set;
    }
    [ReadOnly(true)]
    [Display(Order = 9, Name = "Last Activity")]
    public DateTime LastActivityDate { get; set; }
}

 Note that properties IsApproved and IsLocked are editable and rest of all properties are readonly.Also custom validator class IsLockedOutValidator is used to validate that user is allowed to set IsLocked = false; and is not allowed to set IsLocked =true;

2. Now again to you web project in shared folder add the class IsLockedOutValidator and name the file as IsLockedOutValidator.shared.cs.This will ensure that IsLockedOutValidator class is exposed to client for validations.Add following code to your class IsLockedOutValidator

public class IsLockedOutValidator
{
    public static ValidationResult IsLockedOutValidValue(bool value, ValidationContext context)
    {
        if (value == true)
        {
            return new ValidationResult("You can not lock user accounts ! Please use IsApproved to disable users.");
        }
        else
        {
            return ValidationResult.Success;
        }
    }
}

 3. Now you need to add following methods to you Domainservice class

    public IEnumerable<Models.Security.UserData> GetUsers()
    {
        List<Models.Security.UserData> Users = new List<Models.Security.UserData>();
        foreach (MembershipUser u in Membership.GetAllUsers())
        {
            Users.Add(new Models.Security.UserData
            {
                UserName = u.UserName,
                CreationDate = u.CreationDate,
                Email = u.Email,
                IsApproved = u.IsApproved,
                IsLockedOut = u.IsLockedOut,
                IsOnline = u.IsOnline,
                LastActivityDate = u.LastActivityDate,
                LastLockoutDate = u.LastLockoutDate,
                LastLoginDate = u.LastLoginDate,
            });
        }
        return Users;
    }
   public void DeleteUserData(UserData data)
    {
        Membership.DeleteUser(data.UserName);
    }
   public void UpdateUserData(UserData data)
    {
        //We need to only ensure that two properties are editable and values can be changed.
        MembershipUser u = Membership.GetUser(data.UserName);
        if (data.IsLockedOut == false && u.IsLockedOut)
            u.UnlockUser();
        u.IsApproved = data.IsApproved;
        Membership.UpdateUser(u);
    }

 Please note that if your entity name is UserData then method name used for addition,deletion,of update operation should be Update[EntityName],Delete[EntityName] i.e UpdateUserData,DeleteUserData .. etc.

OK to this stage we have create our class to expose users registered under membership. We have exposed methods to update and delete users from membership. We have also added our custom validation shared class.

Now let’s talk about silverlight client.

To your xaml file add namespace “xmlns:dataGrid=”clr-namespace:System.Windows.Controls;assembly = System.Windows.Controls.Data” (you need to add appropriate ref. Before doing this)

<dataGrid:DataGrid x:Name="grdUsers"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
CanUserSortColumns="True"
AutoGenerateColumns="True"
BorderBrush="Gray" />

To code behind file add

SecurityContext _context = new SecurityContext(); //Assuming this is your web service context

In constructor of code behind

    this.Loaded += new RoutedEventHandler(Configurations_Loaded);
    grdUsers.RowEditEnded += new EventHandler<DataGridRowEditEndedEventArgs>(grdUsers_RowEditEnded);
   void grdUsers_RowEditEnded(object sender, DataGridRowEditEndedEventArgs e)
    {
        _context.SubmitChanges();
    }
   void Configurations_Loaded(object sender, RoutedEventArgs e)
    {
        grdUsers.ItemsSource = _context.UserDatas;
        _context.Load(_context.GetUsersQuery());
    }

Add button “DeleteUser(s)” and on click event add following code

  private void DeleteUser(object sender, RoutedEventArgs e)
    {
        IEnumerable<UserData> list = grdUsers.SelectedItems.Cast<UserData>();
        List<UserData> alist = new List<UserData>();
        alist.AddRange(list);
        foreach (UserData u in alist)
        {
            _context.UserDatas.Remove(u);
        }
        _context.SubmitChanges();
    }

Note that we are removing or changing _context.UserDatas and just using _context.SubmitChnages();This is call the appropriate UpdateUserData or DeleteUserData on web service.

10 thoughts on “Adding User Management to your business application

  1. Hi,

    I’ve tried your code, but after_context.SubmitChanges() call I always get error “Submit operation failed. Value cannot be null. Parameter name: username. Have you ever encountered this problem? Can you help me? I’m using SL4 in VS2010.

    Thanks

    Like

  2. Hello,
    I have the same problem. UserData.Username is null because the object sent to DeleteUserData() is empty – all fields are null or with default values.

    Like

  3. Hello,
    me too.
    {“Value cannot be null.rnParameter name: username”}
    at System.Web.Util.SecUtility.CheckParameter(String& param, Boolean checkForNull, Boolean checkIfEmpty, Boolean checkForCommas, Int32 maxSize, String paramName)
    at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
    at System.Web.Security.Membership.GetUser(String username)
    at AdminAreaSkybyte.Web.UsersManipulationService.UpdateRegistration(UserData data) in C:UsersCristianoDocumentsVisual Studio 2010ProjectsAdminAreaSkybyteAdminAreaSkybyte.WebServicesUsersManipulationService.cs:line 50
    at UpdateRegistration(DomainService , Object[] )
    at System.ServiceModel.DomainServices.Server.ReflectionDomainServiceDescriptionProvider.ReflectionDomainOperationEntry.Invoke(DomainService domainService, Object[] parameters)
    at System.ServiceModel.DomainServices.Server.DomainService.InvokeDomainOperationEntry(DomainOperationEntry domainOperationEntry, Object[] parameters, ChangeSetEntry operation)
    at System.ServiceModel.DomainServices.Server.DomainService.InvokeCudOperations()
    at System.ServiceModel.DomainServices.Server.DomainService.ExecuteChangeSet()
    at System.ServiceModel.DomainServices.Server.DomainService.Submit(ChangeSet changeSet)
    Please can you give me a help?
     

    Like

  4. during writing of the code , the Models.Security highlights Security indication and error. which assembly do i need to reference. also using the SL business app Template, on step 3 where do i place the code. is it in the authentication service.cs or what item do i add to the project.
    great work!

    Like

Leave a comment