考虑一个需要设置会话变量的ASP.NET MVC应用程序。它在整个应用程序中使用。它可以通过读取浏览器cookie上的散列值或者在用户登录后设置。
在WebForms + Master Page模型中,我将检查母版页的Page_Load()。也许不是最终的事件,但它很容易找到。
您如何在ASP.NET MVC中检查并强制存在会话变量?请注意,此问题可能不涉及用户登录详细信息,但可能不涉及其他一些数据(可能是第一次访问时间)。
解决方案尝试
public void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Session["SomeDateTime"] = DateTime.Now.ToString();
// results in Object reference not set to an instance of an object.
// context.Session is null
}
答案 0 :(得分:10)
您有两种选择。
1.在基本控制器的Initialize
功能
假设所有控制器都从基本控制器继承,您可以在基本控制器的Execute()
函数的覆盖中放置所需的逻辑。
public class BaseController : Controller
{
public BaseController()
{
}
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
// check if the user has the value here using the requestContext.HttpContext object
}
{
2。使用Global.asax void Application_PreRequestHandlerExecute(Object source, EventArgs e)
函数
public void Application_PreRequestHandlerExecute(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
// use an if statement to make sure the request is not for a static file (js/css/html etc.)
if(context != null && context.Session != null)
{
// use context to work the session
}
}
注意:第二部分适用于任何ASP.NET应用程序,WebForms或MVC。
至于enforcing
他们有一个特定的会话变量,它真的非常开放。您可以重定向到某个页面,以便他们填写表单或选择一个选项。或者,如果找不到,则可能只有一个默认值设置为某个会话密钥。
修改强>
在玩这个时,我注意到Application_PreRequestHandlerExecute
方法存在一个大问题。正在调用事件处理程序,以便对服务器执行任何请求,无论是.css / .js / .html文件。我不确定这是我的工作站设置方式的问题,还是ASP.NET/IIS的工作原理,所以我确保在实现上述方法时不会在所有请求上调用它。 / p>
出于以前的原因,我用if
语句将要完成的工作包装在会话中。
答案 1 :(得分:2)
我不确定我是否完全理解这个问题,但我是通过覆盖控制器的OnActionExecuting方法来实现的。
在那里,您可以使用代码查看会话变量是否存在。如果没有,请创建它,如果是,则使用它。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Session != null)
{
//TODO: Get value from session etc.
}
base.OnActionExecuting(filterContext);
}
答案 2 :(得分:0)
作为另一种选择,ControllerActionInvoker类调用每个动作方法;它通过控制器工厂分配给控制器。因此,每次调用一个动作时(通过覆盖InvokeAction方法),你都可以将这个动作调用者子类化,检查这个存在...