MVC, not "supposed" to use HttpContext.Current anymore? - asp.net-mvc

Someone in a post here, commented that you should not use HttpContext.Current when using MVC, rather, you should be using ControllerBase.ControllerContext. In some respects, this makes sense, but in other respects it doesn't.
For example, ControllerContext is an instance variable, so everywhere I want to reference, say, my Session variables, I need to have a reference to the Controller? Why are we "not supposed" to be using HttpContext.Current in MVC, when you still can? Is there an "appropriate" MVC "way" to get at my Session object without having to have a reference to the Controller?
I know test-wise, it is better for reasons stated in many other places, but I am working on a project that manages Session variables and references HttpContext.Current and I want to know if there is a better way to get my hands on the Session object without passing a reference to the controller.

This is mainly since unit testing would be very difficult if you use HttpContext.Current since mocking this value is not possible using normal mock frameworks.
HttpContext.Current also makes for more brittle code since it can be abused and misused. For example, you can use it in business layer since it is convenient but it will break if you choose to use an alternative presentation layer other than ASP.NET.
Generally static methods are nowadays frowned upon since they cannot be dependency-injected.

Your one post was due to Mock testing, where depending on the Mock there may not be a HttpContext, only a controller context. Otherwise, I do use HttpContext.Current, just not in my unit tests.

Related

ASP.NET Mvc - AutoMapper Best Practice - Performance

I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).

When was the default AccountController sample changed?

I asked this question over on the asp.net forums, and nobody seems to know what i'm talking about. I'm not sure why that is, but I figured I'll ask here to see if there is anyone with some insight.
Back when MVC2 was released, it included a sample AccountController that wrapped the built-in Membership and FormsAuthentication classes with testable interfaces and services. I read a lot about this, and it was considered a good thing because the Membership and FormsAuthentication classes were not easily testable.
Recently, I generated a new sample project with my up to date (SP1, MVC3, Tools Update, etc..) environment and I find that the AccountController is now much simpler. Gone are the Interfaces and MembershipService and FormsAuthenticationServices. The sample now calls the Membership and FormsAuthentication classes directly.
I'm wondering if anyone knows when this happened and why? Are the testable interfaces no longer considered correct? Was there a technical reason to change this?
The best I can figure is that this happened as a part of the change to remove a possible vulnerability when passing return url's on the open url.
Any insight?
The new model resembles EF's code first approach where the AccountModel is a POCO class. Inside the new API there are no longer abstractions but direct calls to static methods such as FormsAuthentication.SetAuthCookie making this code difficult to unit test. Not something I would recommend basing your real world application code upon.
And, yes, they have fixed a vulnerability inside the LogOn method which was not verifying if the return url is a relative url before redirecting.
Personally I would recommend you using abstractions in order to weaken the coupling between your controller logic and its dependencies. This will make the code easier to unit test.
For me passing all those domain models to views without using view models are total anti-patterns and I have never bothered with them. I simply create an empty project and do the things my way. I mean in the default project they even use ViewBag for Christ sake!
The Account Controller was changed with the MVC3 tools update (When they also included the use of jQuery via Nuget)

Register .net MVC3 ControllerContext into windsor container

With ASP.NET MVC3 what would be the best way to register the requests ControllerContext into castle windsor container? Ultimately I'd like to be able to say
container.Resolve<ControllerContext>();
and have the requests controller context returned.
More detail
The vast majority of my actions are just going to do some validation, authentication, etc.. before sending a message to nservicebus to actually do the work. To avoid having to copy/paste these 20/30 lines of code all over the place I have put them into a handler class which my controllers take a dependency on in the constructor, the actions then call this class which leaves my actions containing just one line of code.
One of the child classes that makes up the handler needs to know about the route that was taken, I could just pass the controller to the handler and then onto this class but it seems a bit messy. It would be nice if there was a way to get Windsor registered to provide it for me.
I don't think you can register the ControllerContext without some very ugly hacks, and IMHO it's not a good idea anyway. The ControllerContext belongs to the controller, it's not meant to be shared around.
However, if you only need the routing information, you can register it like this (UNTESTED!):
container.Register(Component.For<HttpContextBase>()
.UsingFactoryMethod(() => new HttpContextBaseWrapper(HttpContext.Current))
.LifeStyle.PerWebRequest,
Component.For<RouteData>()
.UsingFactoryMethod(k => RouteTable.Routes.GetRouteData(k.Resolve<HttpContextBase>()))
.LifeStyle.PerWebRequest);
Also see ASP.NET MVC & Windsor.Castle: working with HttpContext-dependent services for more details.
I don't know concretely what you're trying to achieve but I'd look into doing it with filters or custom ActionResults instead.
Not really an answer to the original question but I can't stand dubious architectural moves :) It seems for me like ControllerContext isn't a best (well, not even a good one) place to try to extend from. The ModelBinders and ActionAttributes are the places to help with repeating code. They can take model mapping, binding and validation on their own thus freeing controllers from that responsibility.
Well, generally, what you'd really want to do is to use Dependency Injection for Controllers themselves injecting configured instances of somewhat IAuthenticationService and IValidationService (concrete implementations of them would contain all those 20/30 reusable lines of code). Then in Controllers you just call them in one line of code (or even use the MVC3 Global Filters feature to make that completely transparent).

TDD with ASP.NET MVC 1.0

Where can I find a good tutorial on TDD with ASP.NET MVC 1.0? I'd prefer a video tutorial but a text tutorial would be fine as well. I have a new project starting soon and I want to start off on the right foot.
The Storefront Videos from ASP.NET are a must watch series.
Any tutorial on TDD will be helpful for MVC. I've been doing TDD for sometime and found that it was a natural transition in MVC. There are a few peculiarities that I have found that need to be addressed.
You often need to mock up the HttpContext, which means that you need to assign a ControllerContext to the controller after it's created as that's the only way to inject the mock. The context will be used to provide the Session, Request, and Response objects in the controller (also mock them). New HttpContextBase, HttpSessionStateBase, ... classes make this much easier to do.
Because of (1), invest some time in putting together some helper classes in a separate class library that can be used by all of your test projects. These helper classes should contain methods that provide configurable (or multiple methods to provide specific configurations) of the mocked contexts. This will help keep your tests compact.
Use and assign a ValueProvider for testing methods that accept parameters if you aren't using ModelBinding (with corresponding parameters in the signature) for a controller action. This will allow you to use TryUpdateModel/UpdateModel without adding code to your controller to get data from the Request into those methods.
Use a mocking framework -- if that isn't obvious from above. It will be so much easier to write your tests if you mock out the dependencies. Writing your own mocks, IMO, is not worth it, though I know others don't share that opinion. I guess this isn't unique to MVC, but I thought I'd mention it.
Set up a separate set of tests that use reflection to test that appropriate attributes with appropriate properties are getting set on your methods. MVC makes heavy use of attributes for security and other cross-cutting aspects. These need to be tested as well.
Check out here. MVC store front is highly recommended.
I thought that Rob Conery's 'ASP.NET MVC Storefront Starter Kit' http://www.asp.net/learn/mvc-videos/#MVCStorefrontStarterKit were great for demonstrating TDD with ASP.NET MVC.

Difference between HttpContext.Current and Controller.Context in MVC ASP.NET

I am working on an MVC ASP .NET application. I am relatively new to both.
In a controller I am trying to get the current log on user, for which there seem to be two ways of doing this:
System.Web.HttpContext.Current.User.Identity.Name
Or
HttpContext.User.Identity.Name
What is the difference between these? As far as a I can tell within the MVC framework the controller has the current HttpContext stored as a property so these methods are identical. Is that correct?
Yes, they will usually be identical. However, if you're working with additional threads, they will not be; System.Web.HttpContext.Current is threadstatic.
The context provided by the controller (not the static HttpContext.Current) is mockable. If you're interested in unit-testing your code, it's generally far easier to create a mock ControllerContext and set it on the Controller than it is to go through HttpContext.Current. Otherwise ControllerContext.HttpContext points to the same data as HttpContext.Current.

Resources