Search This Blog

Thursday, September 15, 2016

How to provide a specific View layout for users of certain security roles

I would like to quickly promote a recent update to our old Code Example in the support database: https://www.devexpress.com/example=E274
I hope you find this solution helpful. Let me know in case of any questions, suggestions or share your experience with other XAFers on how you are doing a similar task at the moment. Thanks!

Scenario:
This example demonstrates how to show a custom View against a role of the currently logged user. Custom Views were created and customized through the Model Editor for each role separately. For more convenience, custom Views have a name of a role in the Id attribute. For instance: Contact_ListView_Administrators, Contact_DetailView_Administrators, Contact_ListView_Users, Contact_DetailView_Users, etc. You may consider a specific naming convention, for example, to add a role name to the end of the view name. Use User and Admin user names with empty password to login into the application.



Implementation details:
There is E274.Module\Controllers\CustomizeViewAgainstRoleMainWindowController that tracks View showing using theXafApplication.ViewCreating event and replaces the default View's Id with a custom Id found in the Application Model by the role name. 


using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;

namespace E274.Module.Controllers {
    public class CustomizeViewAgainstRoleMainWindowController : WindowController {
        private const string AdministratorsViewSuffix = "Administrators";
        private const string UsersViewSuffix = "Users";
        public CustomizeViewAgainstRoleMainWindowController() {
            TargetWindowType = WindowType.Main;
        }
        protected override void OnActivated() {
            base.OnActivated();
            Application.ViewCreating += Application_ViewCreating;
        }
        //Create corresponding views in the application model first! See the Model.DesignedDiffs.XAFML file for an example.
        void Application_ViewCreating(object sender, ViewCreatingEventArgs e) {
            string roleBasedViewId = String.Format("{0}_{1}", e.ViewID, 
                ((ISecurityUserWithRoles)SecuritySystem.CurrentUser).IsUserInRole(AdministratorsViewSuffix) ? 
                    AdministratorsViewSuffix : UsersViewSuffix);
            if (Application.FindModelView(roleBasedViewId) != null) {
                e.ViewID = roleBasedViewId;
            }
        }
        protected override void OnDeactivated() {
            base.OnDeactivated();
            Application.ViewCreating -= Application_ViewCreating;
        }
    }
}

Alternatively, you can handle the XafApplication.UserDifferencesLoaded event and patch the ViewID of required navigation items under the NavigationItems node as well as the DefaultListView/DefaultDetailView attributes of the BOModel | Class nodes.

1 comment: