2010-01-06 60 views
1

我知道之前已經提出過類似的問題,但我找不到能夠專門處理ASP.NET MVC(以及控制器方面)的重複內容。設置/獲取用戶是否登錄信息的最佳實踐

我的問題如下:

在MVC模式,我的理解是,控制器應該處理使用的HttpContext,以確定誰登錄,如果有的話。這是控制器可以將這些信息呈現給視圖,以便視圖本身不必執行這些查找。

有沒有關於如何做的事實標準?

我目前的設置如下[簡體]

我有一個BaseController,其中我的所有其他控制器繼承。

BaseController,我執行以下重寫:

protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
{ 
    base.Initialize(requestContext); 
    ViewData["IsUserLoggedIn"] = IsUserLoggedIn; // bool property checking HttpContext.User.Identity.IsAuthenticated; 
    ViewData["CurrentUser"] = CurrentUser; // Property returning logged in user, or null. 

} 

然後,自然地,在我的意見,我可以檢查ViewData的值。

怎麼辦?我想知道我的設置是否有問題,如果有,有什麼問題?我對解決方案並不滿意,主要是因爲我對週期不太熟悉,而且我不確定自己的代碼是否放在正確的位置。

我知道這裏可能沒有「一個答案綁定他們」,我接受的答案提供了最深入的見解。

回答

2

我通常將一個加密的元素放入cookie中。該元素可以是任何東西,但我通常把它作爲用戶名。

然後在Global.asax.cs中實現Application_AuthenticateRequest。每次加載頁面時,系統都會調用此方法。在該方法中,我檢查cookie,如果存在,我嘗試加載用戶。如果用戶加載成功,那麼我知道我有一個登錄用戶,並將當前線程當前Principal屬性設置爲該用戶。

一旦在當前線程上設置了CurrentPrincipal,您就可以從Controller,View,Business Layer,以及您的執行路徑中的任意位置訪問該用戶。

如果由於某些原因我不能使用cookie,那麼我會在ViewData中傳遞它(再次加密以防萬一),並將其存儲在隱藏變量中。然後,當Controller :: OnActionExecuting運行時,我執行與AuthenticateRequest中通常所做的相同的工作(即加載用戶並將其放到線程中)。

+0

有趣的方法。您的cookie方案如何與FormsAuthentication cookie相關聯(當然,如果您使用表單身份驗證)? – Terje 2010-01-09 19:28:09

+0

我沒有使用FormsAuthentication,但我確實使用了常規的FormsAuthenticationTicket和HttpCookie。 當用戶嘗試登錄時,我的控制器首先會調用我的域名層以嘗試登錄該用戶。如果成功,那麼我的控制器將創建一個包含我的加密用戶名的FormsAuthenticationTicket對象,將它放入一個HttpCookie中,並將該Cookie放入Response.Cookies集合中。 在過去,我還必須添加一些東西到系統中以跟蹤用戶實際登錄的情況(即,您從票據載入用戶,然後檢查他們是否也已登錄)。 – 2010-01-12 15:23:47

+0

我一直在尋找見解,並且我得到了一些。謝謝。我會研究這種方法,並從我自己的經驗中看到它與我目前使用的相比如何。跟蹤用戶是否登錄;我用我的用戶表中的最後一個活動標記來處理它,並在每次調用BaseController的Initialize時更新它。 – Terje 2010-01-15 12:42:27

0

我有一個BaseController類,所有我的控制器繼承自。它有一個存儲在會話中的「CurrentUser」屬性。我的控制器的完整代碼有更多的邏輯來檢索用戶,但這是基本的想法。

public class BaseController : Controller 
{ 

User _currentUser = null; 
public User CurrentUser 
{ 
    get 
    { 
     if (_currentUser == null) 
      _currentUser = (User)HttpContext.Session["CurrentUser"]; 

     return _currentUser; 

    } 
    set 
    { 
     _currentUser = value; 
     HttpContext.Session["CurrentUser"] = value; 
     } 
    } 
} 


} 

我的模型都從BaseModel類繼承,它也具有CurrentUser屬性。

public class BaseModel 
{ 
    public User CurrentUser { get; set; } 
} 

public class HomeIndexData : BaseModel 
{ 

} 

然後我的控制器將用戶傳遞給允許我使用強類型視圖的模型。

[HttpGet] 
public ActionResult Index() 
{ 
    HomeIndexData data = new HomeIndexData(); 
    data.CurrentUser = this.CurrentUser; 

    return View(data); 
} 

使用這種技術,我也可以使用BaseModel建立一個強類型的母版頁。

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseModel>" %> 
+0

我在以前的項目中使用過類似的方法。大多數情況下,它運行良好,但在某些情況下,擴展BaseModel沒有意義(或不可能)。 (想象直接映射到DataTable類,或使用來自外部項目.dll文件的模型對象)。所以我結束了與ViewData。 另外,您使用Session作爲CurrentUser屬性。這是否有一個好的理由?例如,爲什麼你不能使用Controller.HttpContext.User.Identity?或者更好的問題是,你爲什麼認爲這是一個糟糕的主意? – Terje 2010-01-09 19:34:10

+0

擁有自定義用戶對象而不是User.Identity使其在我們的情況下更具可擴展性。例如,我們的母版頁有一個部分顯示用戶的名字和姓氏,這是我們無法用User.Identity.Name做的。 就個人而言,如果我在應用程序需要的DataTable中有項目,我寧願製作POCO並使用DataTable填充它。 – 2010-01-11 15:00:51