我正在使用 ASP.NET MVC3 和 Razor 语法开发一个简单的测试网站。它具有_LayoutPage.cshtml
作为主模板,用于@HTML.Action
在每个页面的站点顶部打印用户 ID。
我为这个局部视图实现了一个childAction
命名userInfo
,它从中读取用户 IDHTTPContext.Session
并将其打印出来。子动作在一个称为CommonActionController
派生自的控制器中实现Controller
。除了用户 ID,它还从会话中读取另外两个变量并打印出来。
public class CommonActionController: Controller
{
[ChildActionOnly]
public ActionResult userInfo()
{
if(HTTPContext.Session["x-user-id"] != null)
{
ViewBag.UserId = (string)(HTTPContext.Session["x-user-id"]);
ViewBag.UserFirstName = (string)(HTTPContext.Session["x-user-first-name"]);
ViewBag.UserLastName = (string)(HTTPContext.Session["x-user-last-name"]);
ViewBag.UserLoggedinSince = (DateTime)(HTTPContext.Session["x-user-logon-timestamp"]).ToString("f");
}
return PartialView();
}
}
我调用的主页控制器HomeController
具有实际实现的仪表板功能Dashboard
(目前它只打印“仪表板”一词)。在这个控制器中,我重写Controller.OnActionExecuting()
了验证用户 ID 是否存在于会话中的方法。就像前面提到的 childAction 一样,它从 session 中读取总共三个变量。
public class HomeController: Controller
{
public HomeController()
{
}
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
base.OnActionExecuting(ctx);
if(HTTPContext.Session["x-user-id"] == null)
ctx.Result = new RedirectResult("logon/userlogon");
if(HTTPContext.Session["x-user-logon-timestamp"] == null)
ctx.Result = new RedirectResult("logon/userlogon");
if(HTTPContext.Session["x-user-internal-flag"] == null)
ctx.Result = new RedirectResult("logon/userlogon");
}
public ActionResult Dashboard()
{
// nothing to see here
return View();
}
}
我已经稍微清理了代码以删除 debug.print 语句。
根据日志,我看到OnActionExecuting()
方法和userInfo
子操作是同时调用的。在某一时刻OnActionExecuting()
,会话变量为空。在日志中,我可以看到在ChildAction
调用该点之前,会话变量将它们的值保持在OnActionExecuting()
. 一旦childaction
访问它们,它们就会变为空。
当我评论从子操作访问会话的代码时,一切正常。我究竟做错了什么?访问会话变量时我必须采取一些预防措施吗?这是因为我不知道如何异步访问 Session 吗?
我也有以下内容web.config
:
<modules runAllManagedModulesForAllRequests="true"/>