2011-04-08 111 views
2

我有過這樣一個安靜的問題,想到在這裏尋求人羣的智慧。存儲查找值的最佳方法

在我的應用程序中有10個用戶角色允許。它是一個ASP.NET MVC2應用程序。每個控制器方法只能由特定的用戶角色訪問。

爲了實現這個,我創建了一個UserRoleType Enum。

public enum UserRoleType 
{ 
     SystemAdministrator = 1, 
     SeniorLevelExecutive = 2, 
     SeniorManager = 3, 
     JuniorManager = 4, 
     SeniorAdmin = 5, 
     JuniorAdmin1 = 6, 
     JuniorAdmin2 = 7, 
     SeniorAppraiser = 8, 
     JuniorAppraiser = 9, 
     SeniorResearch = 10 
} 

這些值與數據庫中的內容(具有10行的UserRole表)相匹配。

此外,用戶的UserRoleId存儲在[User]表中。只要用戶登錄,我們就從數據庫獲取用戶的roleId,並將其與上面的枚舉進行匹配。例如,如果用戶的roleId是4,這意味着他/她是初級經理。

此應用程序現在不在生產中。我看到的唯一缺點是當我們上線時,如果由於某種原因用戶角色類型表中的值與Enum不匹配,我們將面臨很大麻煩。有什麼選擇?或者我應該專注於確保數據庫中具有匹配的值。任何幫助將不勝感激。

非常感謝!

回答

0

一種簡單的方法的響應將是一個名稱字段添加到的UserRole表,並在你的應用程序啓動時,遍歷您的枚舉,查找該UserRole的通過ID ,並確保名稱與UserRoleType.ToString()相匹配。您應該可以在不進行任何主要代碼更改的情況下執行此操作

private void VerifyUserRoles() 
{ 
    foreach (UserRoleType role in Enum.GetValues(typeof(UserRoleType))) 
    { 
     string dbName = /* SELECT Name FROM UserRole WHERE UserRoleId = (int)role */; 
     if(role.ToString() != dbName) throw new Exception(); 
    } 
} 

更復雜的方法是根本沒有枚舉。如果你想讓角色列表完全由數據庫驅動,那麼使UserRoleType成爲一個帶有私有構造函數的類,並讓它執行數據庫讀取以創建對象列表。 (我想這個模式有個名字,不知道它是什麼。)顯然,這對你現有的代碼來說是一個更重要的改變。

public class UserRole 
{ 
    static List<UserRole> roles = new List<UserRole>(); 

    static UserRole() 
    { 
     foreach (/* SELECT * FROM UserRole */) 
     { 
      roles.Add(new UserRole(...)); 
     } 
    } 

    private UserRole(...){...} 

    // Permissions that the role consists of. 
    private bool CanEditEverything { get; private set; } 

    // Use this whenever you need to display a list of UserRoles. 
    public static ReadOnlyCollection<UserRole> AllUserRoles { get { return roles.AsReadOnly(); } } 

    // If you still need to explicitly refer to a role by name, rather than 
    // its properties, do these and set them in the static constructor. 
    public static UserRole SystemAdministrator { get; private set; } 
} 
+0

謝謝我感謝您的詳細解答。它有助於!! – user629161 2011-04-13 20:52:42

1

我的意見是,如果你不能相信你自己的配置在數據庫和配置文件中,反正你是在小溪。只要確保您的數據庫記錄具有該值作爲特定的列值,而不是自動生成的行ID。

+0

嗯,我相信我的配置,但我想以最好的方式實現。所以如果有人知道除了「確保配置是正確的」之外的任何東西,請回復這個帖子。 – user629161 2011-04-08 19:33:15

+2

此外,您可以爲您的項目創建一個集成測試,併爲枚舉的每個值驗證數據庫是否包含相同的值。然後,您至少會知道環境中的數據庫和配置匹配。 – Tejs 2011-04-08 19:35:33

1

如果RoleID的值不在Enum的範圍內,則不要登錄用戶。

我會發郵件給管理員來解決問題。

0

我這樣做,但添加了適當的約束數據庫,約束描述指示讀者到枚舉。

0

我不確定你應該使用像枚舉這樣的靜態數據結構來模擬動態表單中的元素。擁有UserRole實體類和UserRoleCollection集合類會不會更好?這樣一組用戶角色可以更具動態性。當然,只要您的代碼使用這些數據結構,您就必須確保構建一個故障安全機制,如果遇到未知的用戶角色,則會導致對特定資源的訪問始終被拒絕。自然,如果某個未知角色以某種方式進入數據庫,代碼將生成一條描述性消息。

+0

是的,這是一個更好的。爲了在「添加新用戶」時闡述我的問題,我正在從數據庫填充用戶角色。但是,我們正在驗證每個用戶請求:如果此用戶角色有權訪問此控制器方法。爲此,我們在會話中存儲登錄的用戶角色,並確保用戶角色是否也存在於Enum中。如果用戶是管理員或非管理員,那麼爲每個請求命中數據庫可能不是一個好主意。 – user629161 2011-04-08 20:02:45