如何在.NET Web App(MVC)控制器中正确访问HTTP Headers?
问题原因
你代码报错的核心原因是逻辑位置错误:ASP.NET MVC控制器构造函数执行时,Request、HttpContext等请求上下文对象还未完成初始化,此时直接访问必然触发异常。控制器实例化阶段还没有绑定当前请求的上下文数据,只有进入请求管道的Action执行阶段后,相关上下文才会被注入到控制器实例中。
正确实现方案
推荐两种实现方式,按需选择:
方案1:仅HomeController需要该逻辑
重写控制器的OnActionExecuting方法,该方法会在每个Action执行前触发,且此时请求上下文已经完全可用:
public class HomeController : Controller { private User currUser; protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); try { // 先获取Header,提前判空避免空引用 string ID = Request.Headers["CN userName"] ?? string.Empty; if (ID.Length > 3) { try { ID = ID.Substring(3, 3); } catch { ID = ID.Substring(0, 3); } } string firstName = Request.Headers["X-First Name"] ?? string.Empty; string lastName = Request.Headers["X-Last Name"] ?? string.Empty; string email = Request.Headers["X-Mail"] ?? string.Empty; currUser = new User(ID, firstName, lastName, email, ""); } catch (Exception e) { currUser = new User(/*创建默认用户*/); } } // 其余原有Action方法保持不变 }
方案2:全站所有控制器都需要该逻辑
创建全局Action过滤器,注册到全局过滤器管道中,一次配置所有请求生效:
- 首先定义过滤器类:
public class UserInitFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext filterContext) { var request = filterContext.HttpContext.Request; User currUser; try { string ID = request.Headers["CN userName"] ?? string.Empty; if (ID.Length > 3) { try { ID = ID.Substring(3, 3); } catch { ID = ID.Substring(0, 3); } } string firstName = request.Headers["X-First Name"] ?? string.Empty; string lastName = request.Headers["X-Last Name"] ?? string.Empty; string email = request.Headers["X-Mail"] ?? string.Empty; currUser = new User(ID, firstName, lastName, email, ""); } catch { currUser = new User(/*创建默认用户*/); } // 将用户对象存入请求上下文,后续控制器/视图都可以读取 filterContext.HttpContext.Items["CurrUser"] = currUser; } public void OnActionExecuted(ActionExecutedContext filterContext) { // 不需要额外处理则留空即可 } }
- 在
Global.asax.cs的Application_Start方法中注册全局过滤器:
GlobalFilters.Filters.Add(new UserInitFilter());
- 后续在任意控制器中都可以通过
HttpContext.Items["CurrUser"] as User获取到初始化后的用户对象。
额外注意事项
- IIS传递自定义Header时,如果Header名称包含空格,默认会将空格替换为下划线,若按原名称取不到Header可以先检查IIS的请求日志,确认实际传递的Header名称是否有变化
- 所有Header取值后都要先做非空判断,避免Header不存在时返回null触发空引用异常
- 若需要将用户信息长期存储,可以结合Session或者Cookie使用,避免每次请求都重复读取Header处理
内容的提问来源于stack exchange,提问作者user16768946
相关产品推荐
相关产品推荐

