ASP.NET MVC: Is it good to access HttpContext in a controller? - asp.net-mvc

I've been working with ASP.NET(WebForm) for a while, but new to ASP.NET MVC. From many articles I've read, in most cases the reason that the controllers are hard to test is because they are accessing the runtime components: HttpContext (including Request, Response ...). Accessing HttpContext in a controller seems bad.
However, I must access these components somewhere, reading input from Request, sending results back via Response, and using Session to hold a few state variables.
So where is the best place to access these runtime components if we don't access them in a controller?

when you call a model method in your controller, the Request and Response objects are carrying the same value or outputting to the same source. the "page" is what matters there for these objects.
And one more thing, the Request,Session and Response objects may not be directly referenced in your models so you can use System.Web.HttpContext.Current to get the objects. They will function the same as its called from the controller.
And Controllers meant to be as a bridge between views and models, and models should work even if there isn't any Response or Request value in these objects, so I would use these objects' values as usual parameters to model methods instead of referencing them inside the model. It's the right usage of the MVC concept.

If you really must access access these objects from your controller you could always just abstract them and inject a mock instance of them to isolate your testing to just the controller.

In MVC the HttpContext is actually HttpContextBase. It is completely fine to use these classes directly. If you need to later test your controllers you can mock these classes very easily.
http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx
I see nothing wrong with what you want to do.
Accessing HttpContext in a controller seems bad.
No it is not, it just requires you to think about how you will test your action. If you don't test, then you probably don't even have a problem. I recommend you test though.

Related

Accessing session data from a layout

In my ASP.NET MVC solution I have a number of services.
One of them, SessionService, is used to access the currently selected region and time span.
I want to display those in a layout used to decorate views. What is the best design approach to access those values which are stored in the SessionService?
Right now I'm thinking about using calling a ChildAction from the layout which in turn calls the session service:
_Layout -> aController.ChildAction() -> SessionService.GetRegion()
Is it a good approach or can you recommend anything better?
UPDATE 1:
Other options for passing the values that are possible:
via ViewBag
via ViewModels
However the drawback for these options is the fact that it would be necessary to populate them in each and every action method which would lead to duplication of code (which could be mitigated by means of a filter, but again this will require decorating controllers with the filter).
UPDATE 2 (born in the discussion with O:rvar below):
Another option is to create a base controller which will be populating ViewBag properties upon creation. All other controllers should derive from it.
You should be able to access you session data in the view with the following code:
var region = #Session["Region"].ToString();
Or you could call the controller method as you mentioned with an ajax call and get the session data that way. Using the childaction approach is also a fine way of accomplishing what you want.

Populate model properties inside of the model

I'm developing a webpage in MVC 5 and have been developing in MVC quite sometime now.
I always try/want to learn new ways/best practice of my programming skills. Right now I just stumbled upon something with ViewModels.
For example, I'm using the same ViewModel for multiple pages where I have Dictionary properties to fill my drop down lists.
So normally what I have done is creating a private method in the controller like "SetupViewModel" and then populate the dictionary to the model properties there and inside the model constructor just a "failsafe" creating an empty dictionary.
But for this project I'm working on now I thought that I would try to directly in the model constructor call my service method that returns the list for the ddl and then populate it right there.
Is there any advantages or disadvantages doing this way. What would you say is best practice? Because I can see some problems like, if the database goes down I could still load the page with empty values if I have the "setupViewModel"- method in the controller and with some try/catch or something preventing crash and if it is in the VM it would crash directly if I don't add some fail-safe in the services like returning empty lists if I can't get anything from the DB.
So it's equally much development but at different locations (well I can always have some fail-safe in the service ofc).
But the main question is, what is the best practice, populate model properties from model or controller?
Personally in MVC I see accessing the data layer as a model concern. Controllers are supposed to do as little as possible. So ideally I would in the constructor first initialise the dictionary to an empty one, then in a try..catch (which does nothing on error) get the database value for the dictionary and set it again.

ASP.NET MVC - M V C Responsibilities

I am probably over analyzing here, but with all the reading I have done on MVC, there seem to be so many opinions on how to do things.
Is there a "Best Practices" site or document out there that defines the responsibility of each piece of MVC?
The few questions I have, keep in mind I am using the EF/Repository&UnitOfWork/Service pattern are:
1) How to get the validation results (error messages, etc) of Domain Objects and Business Rules from the Service Layer to the View Models?
2) I am using Domain Objects and a Service Layer that does all the Business Logic, then I send the Domain Objects to the controllers and let them (via AutoMapper) convert them to View Models for the views. What other types of things are the responsibility of the controller? Is the following code OK? Is this too much logic in the controller?:
public ActionResult SomeAction()
{
var model = Mapper.Map<DomainObject, ViewModel>(service.QueryReposForData());
model.SomeCollectionForSelectList = Mapper.Map<IEnumerable<DomainObject>, IEnumerable<ViewModel>>(service.QueryReposForSelectListData());
return View(model);
}
I don't think that the only thing in a controller is one line that returns a view with an object graph mapped to view models?
3) I think it is OK to have properties on the ViewModels that can indicate to a view if something can be hidden for example and then perform that logic in the view? Example:
#if(Model.DisplaySomething)
{
<div>Something to show</div>
}
else
{
<div>Something else to show</div>
}
4) I was thinking of having my services return some sort of TransactionResult object back to the controllers on writes to make it the responsibility of the service to handle the transaction. So I would have an aggregate service that would start a transaction (UnitOfWork) do what ever it needed to do and then return this TransactionResult that could have error messages? I don't think I should make the controller responsible for managing the transaction, but rather have it just pass in a view model mapped to a domain object to the service and let it act on it?
5) Also, how much of ActionFilter's do you want to use? I know it is a huge extensibility point, but I often find myself trying to stuff all of the model creation into a filter.
Just opinions here based on how we work.
We keep our Controllers so skinny they are anorexic, in almost every case.
As for ViewModels, we follow the pattern of having a ViewModel for every view. The Controller loads it up with anything it needs, and kicks it off. From there, the ViewModel drives everything. In our world, the ViewModel is tied directly to the view and contains no code that would/could be used in other parts of the application. It interacts with any part of the larger 'Model' (service layer, etc) that it needs to and packages stuff up for the View to consume.
For your #3 example, I'd say absolutely yes - it's the way we use our ViewModels.
Again, none of this is gospel - just my take on how we handle it.
Excellent questions!
1) How to get the validation results (error messages, etc) of Domain
Objects and Business Rules from the Service Layer to the View Models?
I use EntityFramework in the back-end and implement IValidatableObject both on my models and my entities. On models, I perform cross-field validation, while on entities, I perform cross-entity validations.
2) I am using Domain Objects and a Service Layer that does all the
Business Logic, then I send the Domain Objects to the controllers and
let them (via AutoMapper) convert them to View Models for the views.
What other types of things are the responsibility of the controller?
Is the following code OK? Is this too much logic in the controller?:
This code is perfect. Controllers gather data, transform data into models and feeds them into a view.
3) I think it is OK to have properties on the ViewModels that can
indicate to a view if something can be hidden for example and then
perform that logic in the view? Example:
Yes, this is exactly what a ViewModel is meant for. To capture all data AND logic required for your view to render.
4) I was thinking of having my services return some sort of
TransactionResult object back to the controllers on writes to make it
the responsibility of the service to handle the transaction. So I
would have an aggregate service that would start a transaction
(UnitOfWork) do what ever it needed to do and then return this
TransactionResult that could have error messages? I don't think I
should make the controller responsible for managing the transaction,
but rather have it just pass in a view model mapped to a domain object
to the service and let it act on it?
I struggled with this a bit in my projects. In the end, I moved the SaveChanges method of EntityFramework to the front-end. This allows me to build a transaction in the front-end and then commit it once. Every method in my ApiController which performs an update, create or delete will also do a SaveChanges.
I use ApiControllers as a layer of abstraction between my back-end and actual Controller classes. To elaborate, my application both uses normal Controllers (HTML) and ApiControllers (REST aka Web API). Both types of controllers share a common interface for retrieving data.
Example: http://pastebin.com/uL1NGGqH
The UnitOfWork still resides in my back-end behind a facade. I just expose the SaveChanges to the front-end. Side-effects such as ValidationExceptions are either handled by ASP.NET MVC automagically or captured in custom ActionFilters.
5) Also, how much of ActionFilter's do you want to use? I know it is a
huge extensibility point, but I often find myself trying to stuff all
of the model creation into a filter.
I only used a handful of ActionFilters in the large MVC project I am currently working on. These ActionFilters are mostly used to enforce security and to translate Exceptions (such as ValidationExceptions) to JSON-format so my client-side validation framework can handle it.
Off-topic: You can never over analyze. Asking yourself these fundamental questions of MVC makes you better grasp the concepts of MVC and makes you a better developer in general. Just make sure you don't do it too much in the boss' time ;)
Same here:
base controllers with common actionfilters
Validation is done using DataAnnotation and model validation within the controller.
tiny controllers with injected wrapped context or specific service layer
Automapper mapping ViewModels/EF Pocos.
I don't really bother about implementing UnitOfWork or explicitly using transactions since EF4 automatically creates (if it does not exist) a new transaction for all the changes done within a SaveChanges (http://msdn.microsoft.com/en-us/library/bb896325.aspx. I just have a generic interface exposing the DbSets of the Context as IQuerable and the Add/Delete/Find methods.
But as said it's all personal.

How to access RedirectToAction() function in Models classes in asp.net mvc2

How to access RedirectToAction() function in Models classes in asp.net mvc2. When i try to write it in one of my models classes it says 'The name RedirectToAction does not exists in the current context'
Technically you can't call it because it is a method on the Controller class. It returns a RedirectToRouteResult object, which you could create if you wanted in your model, but you shouldn't. The model is the wrong place to be choosing what type of result to return, this should be a function of the controller.
The reason that you won't want your model to create an ActionResult is that it should be unaware of what type of I/O and display system you are using. Your model should be independent enough that you could use it with a web app, a command-line program, or a desktop app without change. By introducing controller- (or view-)related code into your model you are increasing its coupling and complexity unnecessarily and decreasing your ability to reuse it in another context.

ASP.NET binding object to Request in asp.net mvc

I've created a object that I'd like to have accessible from wherever the request-object is accessible, and to "die" with the request, more or less like how you always in a mvc-application has access to the RouteData-collection. Especially it's important that I have access to this object in the execution of action-filters. And also there need to be created a new object of my class whenever a new request is made to the page (the object needs to be request-safe, ie. only one request modifies that one object).
Any thoughts about how to achieve this?
HttpContext is a good place for this. The Items dictionary could be used to store objects relative to the request.

Resources