从Controller构造器访问Request.Cookies

时间:2009-06-17 06:59:25

标签: asp.net asp.net-mvc cookies

我使用FormsAuthenticationTicket的UserData属性来存储一些特定于用户的信息。我有一个HelperClass,它将此UserData反序列化为一个自定义对象,用于强类型访问。我的控制器设置如下

public class SomeController : Controller
{
    private CookieData _cookieData;

    public SomeController()
    {
        _service = new ForderungsStellerService(new ModelStateWrapper(this.ModelState));
        HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
        _cookieData= GetSessionData.FromCookie(ticket);
    }
}

问题似乎是,在控制器构建时请求为空。从ActionMethod访问Request.Cookies时,此代码段正在运行。

我想让干净的原因在构造函数中填充_cookieData对象。

有没有人对这个问题有所暗示?

最好的问候......

3 个答案:

答案 0 :(得分:6)

我会创建一个理解CookieData的ModelBinder以及如何从Request对象中获取它。我担心使构造函数满意所需的单元测试创​​建代码。如果您使用Model Binder将其作为控制器的参数,则可以避免测试开销。

public class SomeController : Controller
{
  // only need to pass in the data object for unit testing.
  // ModelBinder takes care of DRY
  public ActionResult Index(CookieData cookieData)
  {
  }
}

为什么它在构造函数中不起作用的答案是Controller尚未使用ControllerContext进行初始化。

public HttpContextBase HttpContext {
  get {
    return ControllerContext == null 
      ? null 
      : ControllerContext.HttpContext;
  }
}

如果你真的想在构造函数中做(不),那么使用HttpContext.Request而不是包装器。但通过这样做,你将使你的代码不可测试,你的对齐将下降3点。

答案 1 :(得分:5)

覆盖Controller.Initialize():

protected override void Initialize(RequestContext requestContext) {
  base.Initialize(requestContext);
  // do further initialization here
}

在调用base.Initialize()之后,您可以使用像Request等属性。

答案 2 :(得分:0)

干得好但是在ASP.NET MVC的情况下,它通常意味着使用自定义过滤器属性或类似talljoe显示模型绑定器。

    public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
         HttpCookie cookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
        filterContext.ActionParameters["CookieData"] = GetSessionData.FromCookie(ticket);


         base.OnActionExecuting(filterContext);
     }