MVC项目中如何在视图渲染前从Cookie读取用户信息写入Session值
问题原因
Application_BeginRequest执行时ASP.NET的Session模块还未完成初始化,因此无法访问Session上下文,会抛出你遇到的错误。- 控制器构造函数执行阶段,HttpContext、请求Cookie等上下文对象还未完成注入绑定,因此读取Cookie返回null。
可行解决方案:使用MVC全局动作过滤器(最符合MVC规范的方案)
MVC的动作过滤器会在控制器Action执行前、视图渲染前触发,此时Session和Cookie都已完全加载可用,全局注册后可以覆盖所有请求的执行逻辑。
- 自定义动作过滤器
public class LoadUserInfoFromCookieFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); try { // 优先判断Session已有值的话不需要重复赋值,避免不必要的开销 if (filterContext.HttpContext.Session["UserId"] != null) { return; } var cookiesDataUserinfo = filterContext.HttpContext.Request.Cookies["UserInfo"]; if (cookiesDataUserinfo != null) { filterContext.HttpContext.Session["UserId"] = cookiesDataUserinfo["UserId"].ToString(); // 其他要写入Session的用户字段可以在这里补充 } } catch (Exception ex) { // 异常处理逻辑 string msg = ex.Message; } } }
- 注册全局过滤器
找到项目下App_Start/FilterConfig.cs文件,在RegisterGlobalFilters方法中添加过滤器注册:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); // 新增这行注册自定义过滤器 filters.Add(new LoadUserInfoFromCookieFilter()); } }
只要完成以上两步,所有请求在执行Action、渲染视图前都会自动执行Cookie读取和Session写入的逻辑。
替代方案:使用Global.asax的Application_AcquireRequestState事件
如果你更倾向于在Global.asax中实现,可以替换原来的Application_BeginRequest为Application_AcquireRequestState,该事件在Session加载完成后触发,可正常访问Session:
protected void Application_AcquireRequestState(object sender, EventArgs e) { // 只有请求是激活的Session上下文时才处理,避免静态资源请求触发不必要的逻辑 if (HttpContext.Current.Session != null) { try { if (Session["UserId"] != null) { return; } var cookiesDataUserinfo = HttpContext.Current.Request.Cookies["UserInfo"]; if (cookiesDataUserinfo != null) { Session["UserId"] = cookiesDataUserinfo["UserId"].ToString(); } } catch (Exception ex) { string msg = ex.Message; } } }
注意事项
- 不要在Cookie中存储明文敏感信息,用户标识类Cookie建议加密后存储,避免被篡改伪造。
- 可以按需添加排除逻辑,比如静态资源请求、登录注册等不需要读取用户信息的接口可以跳过处理,减少性能开销。
内容的提问来源于stack exchange,提问作者SYED NAWAZ PRINCE
相关产品推荐
相关产品推荐

