HasFlag 无法识别角色分配

发布于 2024-10-12 22:19:36 字数 966 浏览 2 评论 0原文

我正在使用用 [Flags] 装饰的枚举来控制 MVC2 应用程序中的自动化。下面是我的代码示例:

[Flags]
public enum SecurityRoles
{
    None = 0,
    Executive = 1,
    BackOffice = 2,
    AccountManager = 4,
    Consultant = 8,
    Administrator = 16
}

[TestMethod]
public void MultipleSelectionsTest()
{
    var requiredRoles = SecurityRoles.Executive | SecurityRoles.BackOffice;
    var user1Roles = SecurityRoles.Executive | SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user1HasAccess = user1Roles.HasFlag(requiredRoles);

    var user2Roles = SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user2HasAccess = user2Roles.HasFlag(requiredRoles);


    Assert.IsTrue(user1HasAccess);  //returns true
    Assert.IsTrue(user2HasAccess);  //returns false
}

如您所见,user2Roles 包含 BackOffice 角色,requiredRoles 也包含 BackOffice 角色,但是 user2HasAccess 为 false。这是为什么?我缺少什么? user1HasAccess 为 true。

I'm using an Enum decorated with [Flags] to control autoization within my MVC2 app. Below is my code examples:

[Flags]
public enum SecurityRoles
{
    None = 0,
    Executive = 1,
    BackOffice = 2,
    AccountManager = 4,
    Consultant = 8,
    Administrator = 16
}

[TestMethod]
public void MultipleSelectionsTest()
{
    var requiredRoles = SecurityRoles.Executive | SecurityRoles.BackOffice;
    var user1Roles = SecurityRoles.Executive | SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user1HasAccess = user1Roles.HasFlag(requiredRoles);

    var user2Roles = SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant;
    var user2HasAccess = user2Roles.HasFlag(requiredRoles);


    Assert.IsTrue(user1HasAccess);  //returns true
    Assert.IsTrue(user2HasAccess);  //returns false
}

As you can see, user2Roles containes BackOffice role and requiredRoles also contains BackOffice role, however, user2HasAccess is false. Why is that? What am I missing? user1HasAccess is true.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

◇流星雨 2024-10-19 22:19:36

如果我错了,请纠正我(因为我可能是这样),但是当您执行 Enum 标志检查时,.NET 本质上是对表示标志总和的整数进行二进制算术。

所以有SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant 与二进制值 26 或 11010 相同。

当您调用 Enum.HasFlags 时,正在执行的操作是 return thisInstance & 因此,如果您要根据所需的 SecurityRoles.Executive | flag

角色检查前面提到的标志集。 SecurityRoles.BackOffice 的值是 3 或二进制的 11,数学计算如下:

11010 - 26 Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00010 -  2 BackOffice which really doesn't mean anything useful

然后它会遵循 26 & 。 3 == 3 是错误的。

为了彻底起见,给出了SecurityRoles.Executive |安全角色.管理员 | SecurityRoles.BackOffice | SecurityRoles.Consultant 的值是 27 或二进制的 11011,数学计算如下:

11011 - 26 Executive  | Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00011 -  3 Executive | BackOffice

然后它会遵循 26 & 。 3 == 3 是正确的。

像这样的扩展方法可能是值得的(未经测试)

public static bool HasFlags(this Enum source, Enum[] flags) 
{
    return flags.Any(f => source.HasFlag(f));
}

Correct me if I'm wrong (because I could be), but when you perform Enum flag checks, .NET is essentially doing binary arithmetic on an integer which represents the sum of the flags.

So having SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant is the same as having a value of 26 or 11010 in binary.

When you make the call to Enum.HasFlags, the operation that's being performed is return thisInstance & flag == flag

So if you're checking the previously mentioned flag set against your required roles of SecurityRoles.Executive | SecurityRoles.BackOffice a value of 3 or 11 in binary, the math goes something like this:

11010 - 26 Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00010 -  2 BackOffice which really doesn't mean anything useful

Then it would follow that 26 & 3 == 3 is false.

And for the sake of being thorough, given SecurityRoles.Executive | SecurityRoles.Administrator | SecurityRoles.BackOffice | SecurityRoles.Consultant a value of 27 or 11011 in binary, the math goes like this:

11011 - 26 Executive  | Administrator | BackOffice | Consultant
00011 -  3 Executive | BackOffice
----- 
00011 -  3 Executive | BackOffice

Then it would follow that 26 & 3 == 3 is true.

An extension method something like this, might be worthwhile (untested)

public static bool HasFlags(this Enum source, Enum[] flags) 
{
    return flags.Any(f => source.HasFlag(f));
}
留一抹残留的笑 2024-10-19 22:19:36

感谢您的帮助 Wes P。我能够采纳您的建议并将其与此处找到的扩展结合起来:链接文本 并提出了我自己的扩展来解决问题

这是我的扩展。它使用我在上面的链接中找到的扩展方法中找到的 GetFlags() 方法。

public static bool HasFlags(this Enum userRoles, Enum requiredRoles)
        {
            var hasFlags = false;
            var userRolesList = userRoles.GetFlags();
            var requiredRolesList = requiredRoles.GetFlags();

            foreach (var role in userRolesList)
            {
                var role1 = role;
                hasFlags = requiredRolesList.Any(securityRole => role1.CompareTo(securityRole) == 0);

                if(hasFlags)
                    break;
            }

            return hasFlags;
        }

Thanks for your help Wes P. I was able to take your suggestion and combine it with the extension found here: link text and came up with my own extension to solve the problem

Here's me extension. It uses the GetFlags() method found in the extension methods i found in the link above.

public static bool HasFlags(this Enum userRoles, Enum requiredRoles)
        {
            var hasFlags = false;
            var userRolesList = userRoles.GetFlags();
            var requiredRolesList = requiredRoles.GetFlags();

            foreach (var role in userRolesList)
            {
                var role1 = role;
                hasFlags = requiredRolesList.Any(securityRole => role1.CompareTo(securityRole) == 0);

                if(hasFlags)
                    break;
            }

            return hasFlags;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文