Loading

C#开发之WPF项目中权限控制的实现(attribute)

1 功能描述

实现一个权限检查机制,以确保用户根据其权限级别进行相应的操作。定义四级权限:Operator, Maintenance, Supervisor, Administrator,每一级权限都有其特定的操作范围。能够根据用户的权限级别判断用户是否有权执行特定的操作。

2 设计分析

如果实现为接口形式,那么每次在需要控制权限的地方,都需要显式调用接口,并且传入当前操作的required_level,非常麻烦且不利于项目的扩展和维护。因此需要设计一个更为易用的权限控制方式。

经过查询网络资料,在.Net web应用中,常常使用MVC提供的AuthorizeAttribute来进行权限控制。虽然wpf项目中似乎并没有相关的特性提供,但可以根据属性注入的思想自己实现一个类似功能。

c# MVC利用AuthorizeAttribute验证用户是否登录

3 实现方法

3.1 自定义权限属性

   [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
   public class ControlAccessAttribute : Attribute
   {
       public int RequiredLevel { get; private set; }
   
       public ControlAccessAttribute(int requiredLevel)
       {
           RequiredLevel = requiredLevel;
       }
   }

3.2 自定义Page并重写

具体地,自定义AccessControlledPage继承自Page,重写onInitialized函数。在页面初始化时,获取当前用户等级,并获取包含ControlAccessAttribute的控件,根据其属性(所需权限等级)重设控件的可见性/可用性。

public class AccessControlledPage : Page
{
    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        ApplyControlAccess();
    }

    private void ApplyControlAccess()
    {
        int currentUserLevel = 0;

        var propertiesWithAttributes = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Select(prop => new { Property = prop, Attribute = prop.GetCustomAttribute<ControlAccessAttribute>() })
    .Where(prop => prop.Attribute != null);

        foreach (var prop in propertiesWithAttributes)
        {
            var control = prop.Property.GetValue(this) as UIElement;
            if (control != null)
            {
                //control.Visibility = currentUserLevel >= prop.Attribute.RequiredLevel ? Visibility.Visible : Visibility.Collapsed;
                control.IsEnabled = currentUserLevel >= prop.Attribute.RequiredLevel;
            }

        }
    }
}

3.3 使用属性修饰相关控件

  • 所有需要权限控制的页面必须继承自AccessControlledPage

  • xaml文件中需要将Page改为重写的AccessControlledPage

  • 所有需要权限控制的控件,需要进行后置声明,并使用属性修饰。

使用实例如下:

public partial class ControlPage : AccessControlledPage
{
    [ControlAccess(2)]
    public Wpf.Ui.Controls.Button FanButton_ => FanButton;
    
    // ...
}

4 运行实例

设置当前用户权限等级为0,而当前button所需权限为2,可见该控件已经是无法点击的状态:

效果示例

posted @ 2024-04-07 15:04  rthete  阅读(1111)  评论(0)    收藏  举报