XAF has a great security system which can be used to protect our data either at client or server side. There is also great support for modifying the Security behavior at runtime using a permission matrix. However we need to provide initial before distributing our application. In this post we are going to discuss a way connecting methods that describe permission policies with our domain objects using metadata (Attributes).
For supplying initial data XAF provides a well documented approach through ModuleUpdaters. We can use them and write methods that create initial permissions. There are also many extension methods that can help us write faster code,

Full permission policy
This policy can be applied to any role and give full permission for the related objects. To connect a domain object with a method we need to do the following:
- Define a FullPermissionAttribute as,
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class FullPermissionAttribute : Attribute {
}
- Decorate all related objects
[FullPermission]
public class MovieArtist : VideoRentalBaseObject {
[FullPermission]
public class Artist : VideoPerson {
- With the use of XAF’s sub types info metadata API write an abstract algorithm that will enumerate all domain objects and assign full permission to them for a certain role
public static void CreateFullPermissionAttributes(this SecuritySystemRole systemRole, bool defaultAllowValues = true) {
var persistentTypes = XafTypesInfo.Instance.PersistentTypes.Where(info => info.FindAttribute<FullPermissionAttribute>() != null);
foreach (var typeInfo in persistentTypes) {
systemRole.CreateTypePermission(typeInfo.Type, defaultAllowValues);
}
}
public static SecuritySystemTypePermissionObject CreateTypePermission(this SecuritySystemRole systemRole, Type targetType, bool defaultAllowValues = true) {
var permission = systemRole.CreateTypePermission(targetType);
permission.TargetType = targetType;
permission.AllowDelete = defaultAllowValues;
permission.AllowNavigate = defaultAllowValues;
permission.AllowRead = defaultAllowValues;
permission.AllowWrite = defaultAllowValues;
permission.AllowCreate = defaultAllowValues;
return permission;
}
- Invoke the CreateFullPermissionAttributes form the roles you want to apply inside the ModuleUpdater’s
public override void UpdateDatabaseAfterUpdateSchema() {
base.UpdateDatabaseAfterUpdateSchema();
var employersRole = ObjectSpace.GetRole<SecuritySystemRole>("Employers");
employersRole.CreateFullPermissionAttributes();
Permission Behavior policy
A common policy for an application is a “settings” policy. Which really means that for certain roles like the employee role there should be limited access to objects that store “settings” data. To implement this we can follow the follow steps
- Define an attribute to decorate our objects as in previous step. This time we do not know the policy name (settings) so we design this as an Enum parameter in the ctor.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PermissionBehaviorAttribute : Attribute {
readonly string _name;
public PermissionBehaviorAttribute(object @enum) {
if (!@enum.GetType().IsEnum)
throw new NotImplementedException();
_name = Enum.GetName(@enum.GetType(), @enum);
}
public PermissionBehaviorAttribute(string name) {
_name = name;
}
public string Name {
get { return _name; }
}
}
- Design an enumeration to hold all possible security policies
public enum PermissionBehavior {
Admin,
Settings,
ReadOnlyAccess
}
- Decorate related objects
[PermissionBehavior(PermissionBehavior.ReadOnlyAccess)]
public class Language : VideoRentalBaseObject {
- Create a method to describe the ReadOnlyAccess permission policy inside ModuleUpdater.
public class Updater : ModuleUpdater {
void ReadOnlyAccesPermissionBehaviour(SecuritySystemRole securitySystemRole, ITypeInfo typeInfo) {
securitySystemRole.SetTypePermissions(typeInfo.Type, SecurityOperations.ReadOnlyAccess, SecuritySystemModifier.Allow);
}
- With the use of XAF’s sub types info API write an abstract algorithm that will enumerate all domain objects and invoke a delegate with same parameters as the method in step 4
public static void CreatePermissionBehaviour(this SecuritySystemRole systemRole, Enum behaviourEnum, Action<SecuritySystemRole, ITypeInfo> action) {
var typeInfos = XafTypesInfo.Instance.PersistentTypes.Where(info => {
var permissionBehaviorAttribute = info.FindAttribute<PermissionBehaviorAttribute>();
return permissionBehaviorAttribute != null && permissionBehaviorAttribute.Name.Equals(Enum.GetName(behaviourEnum.GetType(), behaviourEnum));
});
foreach (var typeInfo in typeInfos) {
action.Invoke(systemRole, typeInfo);
}
}
- Invoke the CreatePermissionBehaviour inside the ModulerUpdater feeding it with the ReadOnlyAccesPermissionBehaviour method of step 4
employersRole.CreatePermissionBehaviour(PermissionBehavior.ReadOnlyAccess, ReadOnlyAccesPermissionBehaviour);
In this post we created reusable algorithms from any XAF projects to help us speeding up the configuration of the initial permissions. When of course talking about code reusability we talk about money saving!
P.S. In a real world application the above coding will be converted to a permission matrix UI representation like,

We would appreciate your feedback on this post. Has it been useful to you? Feel free to contact us with any further questions
Next post will be about what else? its model time!
Happy XAFing as always.


DashboardView is a type of XAF View that is used to display several Views side-by-side. However XAF by default does not provide any connection between these Views. In this post, with the help of XAF model, we will discuss a few abstract connection mechanisms and possible uses of dashboards.
Cascading ListViews
In a dashboard, in order to connect the ListViews we need first to connect their models. This can be done using the following interfaces,
public interface IModelDashboardViewFilter : IModelNode {
[DataSourceProperty("FilteredColumns")]
IModelColumn FilteredColumn { get; set; }
[DataSourceProperty("DataSourceViews")]
IModelListView DataSourceView { get; set; }
}
[ModelAbstractClass]
public interface IModelDashboardViewItemEx : IModelDashboardViewItem {
IModelDashboardViewFilter Filter { get; }
}
and then extend XAF’s model, see also our documentation on extending the model
public void ExtendModelInterfaces(ModelInterfaceExtenders extenders) {
extenders.Add<IModelDashboardViewItem, IModelDashboardViewItemEx>();
}
This design allows us to use Model Editor to connect our views. In the following image we see that the selected objects of the Customer_ListView_Calendar are going to filter the Calendar list view on the Receipt.Customer field.

Next we see this dashboard view in action, a SchedulerListEditor on the right is filtered by a GridListEditor,

Following we see this technic applied to 3 ListViews. The selected pie section of the left View filters the pivot which in its turn filters a LayoutListEditor!

Cascading views are as well useful for filtering reports, so by selecting objects on the left View we create a report on the right view and everything is inside a Tabbed MDI environment!

Of course we haven’ wrote the code yet but this is the easy part. XAF’s API is so rich and so well designed that is like we speak our native language! The great thing when XAFing is that our code is fully reusable from any project since it has no knowledge of our domain objects.
Let try to form our requirement in English first:
For each ListView in a Dashboard we need to filter another View when the selection is changed
And now in XAF language
:
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
foreach (var result in View.Items.OfType<DashboardViewItem>()) {
var frame1 = result.Frame;
if (frame1 != null && frame1.View is ListView) {
var listView = ((ListView)frame1.View);
DashboardViewItem result1 = result;
listView.SelectionChanged += (sender, args) => OnSelectionChanged(new SelectionChangedArgs(listView, result1));
}
}
void OnSelectionChanged(SelectionChangedArgs selectionChangedArgs) {
var dataSourceListView = DataSourceListView((IModelListView)selectionChangedArgs.DashboardViewItemModel.View);
if (dataSourceListView != null) {
var dashboardViewItems = View.Items.OfType<DashboardViewItem>();
foreach (var dashboardViewItem in dashboardViewItems) {
var modelDashboardViewItemEx = (IModelDashboardViewItemEx)dashboardViewItem.GetModel(View);
FilteredListView(dataSourceListView, dashboardViewItem, modelDashboardViewItemEx);
}
}
Controlling DashboardViewItem visibility
Cascading views are really powerful and soon we will have the need to hide an intermediate view in the chain but being able to filter other views upon it. Therefore we need to add a Visibility property in our model and handle it from our code.
public interface IModelDashboardViewItemEx : IModelDashboardViewItem {
[DefaultValue(ViewItemVisibility.Show)]
ViewItemVisibility Visibility { get; set; }
and in a reusable from all projects controller implement the required logic.
protected override void OnActivated() {
base.OnActivated();
((ISupportAppearanceCustomization)View.LayoutManager).CustomizeAppearance += LayoutManagerOnCustomizeAppearance;
}
void LayoutManagerOnCustomizeAppearance(object sender, CustomizeAppearanceEventArgs customizeAppearanceEventArgs) {
var modelDashboardViewItem = View.Model.Items.OfType<IModelDashboardViewItemEx>().FirstOrDefault(item => item.Id == customizeAppearanceEventArgs.Name);
if (modelDashboardViewItem != null)
((IAppearanceVisibility)customizeAppearanceEventArgs.Item).Visibility = modelDashboardViewItem.Visibility;
}
Displaying HTML Messages
A DashboardView does not have direct dependency with our domain objects. Therefore we can easily use it, even at runtime, to display static text view items and other controls (ControlDetailItem) or images (StaticImage).

XAF has great support for HTML Formatting so a Static Text like “<u><b>Hello</b></u>” will render the following:

Simulating View inheritance
XAF does not support View inheritance however we can extend our model and support it. Lets take the case that we have a very complex listview and we want to display it in both in MasterDetail and ListViewOnly modes without the need to support two View versions. For this we have to extend again the model, this time by a MasterDetailMode property and implement the logic in a ViewController.
[ModelAbstractClass]
public interface IModelDashboardViewItemEx : IModelDashboardViewItem {
MasterDetailMode? MasterDetailMode { get; set; }
public class DashboardInteractionController : ViewController<DashboardView>, IModelExtender {
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
ResetMasterDetailModes();
}
void ResetMasterDetailModes() {
foreach (var masterDetailMode in _masterDetailModes) {
masterDetailMode.Key.MasterDetailMode = masterDetailMode.Value;
}
_masterDetailModes.Clear();
}
protected override void OnActivated() {
base.OnActivated();
foreach (var item in View.GetItems<DashboardViewItem>().Select(item => item.GetModel(View)).OfType<IModelDashboardViewItemEx>()) {
AssignMasterDetailModes(item);
}
}
void AssignMasterDetailModes(IModelDashboardViewItemEx modelDashboardViewItem) {
if (modelDashboardViewItem.MasterDetailMode.HasValue) {
var modelListView = modelDashboardViewItem.View as IModelListView;
if (modelListView != null) {
_masterDetailModes.Add(modelListView, modelListView.MasterDetailMode);
modelListView.MasterDetailMode = modelDashboardViewItem.MasterDetailMode.Value;
}
}
}
Since XAF has a great modularization system the core classes/implementations of the above ideas are included in this zip file. However we will not update the contents of the zip file. For locating up to date versions each file in the zip has an OnlineRepoLocation attribute that points to eXpandFramework’s Github repository.
This post adds a few more tools in our development library that can leverage the XAF power using the Model. When we “model” there are three basic advantages:
- We can use these model tools at runtime. For this XAF already provides a runtime time Model Editor.
- We create robust unbreakable code and since we model instead of developing we mostly have no bugs only wrong configuration!
- Implementations are reusable from all our projects!
Next post we will boost our R&D times even further and discuss a bit about Security system policies.
P.S.: We are preparing detailed samples demonstrating all the above ideas
, stay tuned!
If some of you have invented similar ways to connect your dashboards. You can use our support center and share them with the rest of the community.
Happy XAFing!

