Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用反射和枚举对MVC应用程序访问进行逻辑控制是否安全?_C#_Database_Asp.net Mvc 3_Reflection_Enums - Fatal编程技术网

C# 使用反射和枚举对MVC应用程序访问进行逻辑控制是否安全?

C# 使用反射和枚举对MVC应用程序访问进行逻辑控制是否安全?,c#,database,asp.net-mvc-3,reflection,enums,C#,Database,Asp.net Mvc 3,Reflection,Enums,为了管理对网站的访问,我创建了一些必要的实体 目标是为我的MVC应用程序的某个控制器的操作方法使用自定义权限属性 [Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)] public ActionResult SomeAction() { } 对于此操作,我有两个枚举 [Flags] public enum CrudType { CanCreate = 0x1, CanRead = 0x2,

为了管理对网站的访问,我创建了一些必要的实体

目标是为我的MVC应用程序的某个控制器的操作方法使用自定义权限属性

[Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)]
public ActionResult SomeAction()
{
}
对于此操作,我有两个枚举

[Flags]
public enum CrudType
{
    CanCreate = 0x1,
    CanRead = 0x2,
    CanUpdate = 0x4,
    CanDelete = 0x8,
}

[Flags]
public enum PermissionType
{
   SomePermissionName = 0x1,
   //... 
}
现在我想要下面的方法来检查权限

public static bool CanAccess(RolePermissions rp, CrudType crudType)
{
    var pInfo = rp.GetType().GetProperties();
    var res = pInfo.FirstOrDefault(x => x.Name == crudType.ToString());
    if(res != null)
    {
        return Convert.ToBoolean(res.GetValue(rp, null));
    }
    return false;
}
它工作得很好,但是在这里使用反射安全吗?这是一种好的款式吗
还有一个问题是关于这段代码

var permission = PermissionService.GetByName(permissionType.ToString());
在这里,我试图使用
PermissionType
enum中的某个命名常量从数据库中获取权限对象
在这两种情况下,正确的工作取决于枚举与某些表字段或记录之间的关系。另一方面,我有一个很好的逻辑控制机制(在我看来)。
这样好吗

另一次编辑
在您的情况下,为
RolePermissions
类创建一个只读属性
ExistingPermissions
,并在该属性getter中将四个布尔值合并为一个
CrudType
。然后您就可以执行
rp.ExistingPermissions.hasvag(permissionToCheck)

已编辑

感谢@DevDelivery指出了这个问题-很好。不幸的是,固定的解决方案并不像我希望的那样漂亮,所以在这种情况下,使用@DevDelivery的方法可能是有意义的

由于将
CrudType
作为“位字段”,因此可以使用更简洁的方法(代码更少,可读性更好):


与您的解决方案相比的缺点是,如果您添加了更多操作(到现有的
CanRead
等),您将不得不修改此方法。

使用反射会影响性能,并且后期绑定意味着更改枚举的名称 或属性将不会被编译器捕获

另外,这段代码很难理解,因此很难维护

这里只有4个选项可供检查。简单的switch语句更容易、更快、更干净


如果您试图允许对数据库进行更改或允许第三方组件引入新权限,则使用反射是有意义的。

这在ASP.NET成员资格APi中不可用吗?我真的不喜欢成员资格。此外,我想使用我自己的类,自己的表,自己的控件等等,除了自己的类,自己的表,自己的控件之外,还有什么原因你不喜欢?当我考虑转到会员APi时:(好的。第一个原因。第二个原因-我很方便自己控制一切。当然这是一个品味的问题…哇。一个经过深思熟虑、陈述正确的问题,有正确的代码。现在这是一个好问题。我只希望我能给你一个好的答案…不幸的是,我的反应很弱。这里的问题是角色权限属性是布尔型的。或者,使用一组布尔型只会得到另一个布尔型。@DevDelivery-很好的捕获,这确实不起作用。修复后的解决方案似乎没有那么好。
public static bool CanAccess(RolePermissions rp, CrudType permissionToCheck)
{
    CrudType existingPermissions = 
                                SetPermissionFlag(CrudType.CanCreate, rp.CanCreate) |
                                SetPermissionFlag(CrudType.CanRead, rp.CanRead) | 
                                SetPermissionFlag(CrudType.CanUpdate, rp.CanUpdate) |
                                SetPermissionFlag(CrudType.CanDelete, rp.CanDelete);

    return existingPermissions.HasFlag(permissionToCheck);
}

public static CrudType SetPermissionFlag(CrudType crudType, bool permission)
{
    return (CrudType)((int)crudType * Convert.ToInt32(permission));
}