2010-05-10 49 views
0

我试图为我的ASP.NET MVC应用程序创建一个授权方案,其中Enum用于设置权限。例如:比特菲尔德与3个国家...?

[Flags] 
enum Permissions 
{ 
    ReadAppointments = 1, 
    WriteAppointments = 2 | ReadAppointments, 
    ReadPatients = 4, 
    WritePatients = 8 | ReadPatients, 
    ReadInvoices = 16, 
    WriteInvoices = 32 | ReadInvoices 
    ... 
} 

但是我不是那么喜欢这个,因为它确实没有说清楚Write总是包含Read。

然后,我意识到一个要求是用户可能无权访问例如约会。本质上,我想要一个有3个状态的“位域”:无,只读,完整(读/写)。我想仍然使用enum位域,因为它很容易存储在数据库中(作为int)。另外,很容易看到是否设置了权限。

有没有人有任何想法如何使用枚举容易地完成这项工作...或者我会完全错误的方向吗?

编辑:我真的试图避免在数据库中存储权限定义,因为我真的希望事情是可以改变的,而不必在数据库端修改太多。知道一个大型应用程序如何做到这一点真的很好。

+0

保持它在低级别的4个状态:无,x但不是Y,Y僵尸不是X,X和Y.此外,而不是1,2, 4,8,16使用1移位0位,1移位1位,1移位2位等。 – 2010-05-10 17:33:20

回答

3

我可能会这样做为每个区域(发票,患者,约会)使用单个枚举来覆盖每个区域的单独字段。

enum Permission { None, ReadOnly, ReadWrite }; 

对我来说,这是比较容易理解和管理,并且它不结合一堆无关的东西(我应该说“看似无关的”,因为我不知道你的应用程序的任何东西)。

+0

当然,这也是我的想法,但怎么可以很容易地存储在数据库中的每个领域。 – TheCloudlessSky 2010-05-10 17:41:51

+0

我会为这些东西使用三个单独的tinyint字段(sql server) - int也可以工作,但比您需要的大。 – Ray 2010-05-10 17:43:26

+0

好吧,但随着应用程序的增长,我必须不断添加更多的字段到表...不是很好的海事组织。 – TheCloudlessSky 2010-05-10 17:44:01

-1

错误的方向。你的应用程序将会增长,那么位域将不再足够,并且你需要进行大量的返工。更好地从一开始就获得“正确”。

+1

好的,如果是错误的方向,你认为什么是“正确的”? – TheCloudlessSky 2010-05-10 17:39:08

0

将不值0意味着没有权限?即:

0是不能修改的约会,患者,或发票

1被读取约会,但不能修改他人

2是写约会,但不能修改他人

3是读/写约会,但不能修改其他人

4是读病人,但不能修改其他人。

所以如果你有...

51是:

读/写发票和读/写约会,但患者没有访问...

0

严格地说,你可以”除了两个可能的值以外的任何其他值都不能超过10个可能值的单个(十进制)数字位。基数2意味着两个值。

即便如此,也不要将业务特定的权限存储为二进制值;你后悔。单独存储它们。随意使用位字段来定义的具体信息的权限(无/读/写/等),但是不是权限本身的性质。

为什么是这个社区Wiki?

+0

当然,我站在一点,只能承担这两个价值。我对这个方法更感兴趣。 编辑:必须有意外点击社区维基...我怎样才能关闭它? – TheCloudlessSky 2010-05-10 17:39:40

+1

@TheC一旦你使它CW,你不能撤消它 – Earlz 2010-05-10 17:57:31

0

我借和从改性这个例子:C# vs Java Enum (for those new to C#)

不管我不会用枚举,我会用一个类这将允许更大的灵活性。像这样的东西可能会有所帮助,只是不要添加病人和发票,因为这与读取和写入权限问题正交变化。

有许多方法可以进行位操作,并且应该在单独的代码层上完成。如果你需要对序列化进行位操作(对文件或数据库),那么你应该把代码放在那里。

我不使用C#太多,所以语法可能关闭,我主要是做Java。无论如何,基本的概念应该清楚这里:

public class Permissions 
{ 
    public static readonly Permissions NONE = new PERMISSIONS("NONE",false,false); 
    public static readonly Permissions READ = new PERMISSIONS("READ",true,false); 
    public static readonly Permissions FULL= new PERMISSIONS("FULL",true,true); 

    public static IEnumerable<Permissions> Values 
    { 
      get 
      { 
        yield return NONE; 
        yield return READ; 
        yield return FULL; 
      } 
    } 

    private readonly string name; 
    private readonly boolean read; 
    private readonly boolean write; 
    private readonly int bits; 

    Permissions(string name, boolean read,boolean write) 
    { 
      this.name = name; 
      this.read = read; 
      this.write= write; 
      this.bits = bits; 
    } 

    public string Name { get { return name; } } 

    // returns true if read permission is granted 
    public double isReadable { get { return read; } } 

    // returns true if write permission is granted 
    public double isWriteable { get { return write; } } 

    public override string ToString() 
    { 
      return name; 
    } 

    // returns bit field 
    public int bits { get { return write ? 1 : 0 | read ? 2 : 0; } } 
}