tags:

views:

163

answers:

3

I recently asked a question about using the Page.User or HttpContext.Current.User in the View. It was recommended I pass the user info through the Controller instead? I've seen this in other posted answer as well.

Why is it recommended to pass the user info through the controller and not use Page.User or HttpContext.User?

A: 

It loosens the coupling between your controller and the other classes in the application. By using more of a Dependency Injection pattern, you can increase the testability of the controller. This is because in your tests you would not need to simulate concepts like HttpContext but could simply pass in the user object.

McKAMEY
Wait... Using HttpContext in the view has zero dependency because Views are mostly untestable outside of the browser. Using HTTPContext within the controller only ADDS a coupling and decreases testability.
jfar
It sounded like mawaldne was wanting to access HttpContext in the controller which is what I was talking about. The controller should avoid using HttpContext/HttpRequest directly so as to improve testability.
McKAMEY
A: 

Controller should provide all necessary data for view. This makes views more testable. If you use only view model inside view, you can easily write test:

  1. Create view model.
  2. Create view object.
  3. Pass model to view.
  4. Render view.
  5. Check if result is correct.

If you used HttpContext.Current inside of view, you would have to set it up first in your tests, which may not be easy and would add additional dependencies.

LukLed
+1  A: 

This would only be pragmatic if your automating your view testing with Selenium or using some other tool to check your HTML output.

If that is the case using HTTPContext inside your controllers is probably a really bad idea because that will only increase the coupling between your controller actions and HTTPContext.

To gain maximum testability you probably want to setup a controller factory that can inject the User bits into your controller when MVC calls it. That way your action methods remain decoupled from HTTPContext and you gain testability.

If your not using a automated view testing tool it doesn't really matter were you call your HttpContext.User information unless your doing a lot of logic in your view. For example if( HttpContext.User.IsAuthenticated ) or something. If that is the case you can just stick it inside a control and use RenderPartial or bake the logic bits into your viewmodels.

A recommended best practice for MVC is to keep your Views as dumb as possible. Yet, I'd advice against getting all dogmatic about MVC and patterns and what not. Because MVC does not have baked in SubController functionality there are many areas were breaking the MVC pattern is not only encouraged but impossible to not break otherwise. ( see MVC 2 RenderAction, RenderPartial, MasterPages with controls )

jfar