2009-06-17 41 views
4

我正在使用FormsAuthenticationTicket的UserData属性来存储某些用户特定的信息。我有一个HelperClass将这个UserData反序列化为一个用于强类型访问的自定义对象。我有我的控制器设置如下访问控制器构造函数中的Request.Cookies

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对象在DRY原因的构造函数中填充。

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

问候......

回答

6

我会创造一个了解CookieData以及如何把它弄出来Request对象的ModelBinder的。我担心创建构造函数所必需的单元测试创​​建代码。如果您使用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点。

+0

使用ModelBinder是一个聪明的主意。感谢它。解决了我的问题... – Gordon 2009-06-17 08:25:14

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); 
    } 
5

覆盖Controller.Initialize()调用base.Initialize后

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

属性,如请求等将提供给你()。

+0

也是一个正确的解决方案。会工作,但它使单位测试更加困难,因为它应该是。 – Gordon 2009-06-17 10:13:49