I'm writing an ASP.NET MVC 3 app and I'm finding myself writing this line rather often in my action methods:
var user = _session.Single<User>(u => u.UserName == User.Identity.Name);
(Obviously used in conjunction with the AuthorizeAttribute)
There are other things that get repeated quite often but this one is the most prominent and I end up having 3 actions next to each other, each needing to retrieve the authorized user.
So this needs DRY-ing up:
Should I write an ApplicationContoller from which all other controller inherit and expose a User property there or should I add this to my IAdminService and expose it as a method?
Is an ApplicationController something to avoid or to embrace in ASP.NET MVC?
If you are finding yourself repeating this logic then a custom model binder for the User type might help:
public class UserModelBinder : DefaultModelBinder
{
private readonly ISession _session;
public UserModelBinder(ISession session)
{
_session = session;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var username = controllerContext.HttpContext.User.Identity.Name;
return _session.Single<User>(u => u.UserName == username);
}
}
and once you register the binder your controller action might look like this:
[Authorize]
public ActionResult Foo(User user)
{
// ...
}
As a person who doesn't really like controller super-types I would consider using Dependency Injection and use constructor injection to "inject" the user.
o/c this has some drawbacks. This means you'll have to a field for every use in your controller, and also have to create a binding in your IOC tool. This also assumes you're using an IOC container.
Regarding the other options:
Exposing it in the IAdminService gives you the added benefit of being availiable in other places, and not just in the Controller. So that's a plus. Just be certain that you don't clutter your interface too much.
Using it in a base controller is also tempting at first, but I've found that controller base types get bloated and mismanaged as more and more functionality is added, because there's no multiple inheritance and people need some of this and some of that... Things can get ugly. Not to mention that if you use the AsyncController you'll have two base-types to manage.
Basically, between your two option's I'd use the interface.
No matter what you do, you can still add a method to the interface and also abstract it behind a User property in a base Controller.
Related
I currently have a custom PrototypingControllerFactory that looks for a custom [Prototype] attribute on the action method being invoked for the current request, and depending on whether the attribute is present or not will inject a different implementation of an interface ISomeService. (In this case ISomeService more or less abstracts a messaging service, so the mock implementation allows returning "canned" results when the real implementation is not yet ready to handle a particular message).
So for example, if I have a controller class like so:
public class MyController : Controller
{
private readonly ISomeService _someService;
public MyController(ISomeService someService /*, .... other dependencies */
{ _someService = someService; //... etc }
public ActionResult Action1()
{
//...
_someService.SomeMethod();
//...
}
[Prototype]
public ActionResult Action2()
{
//...
_someService.SomeMethod();
//...
}
}
Then when Action1 is invoked from an http request, _someService should use the production implementation of ISomeService, but when Action2 is invoked, _someService should have a Mocked version of ISomeService.
From a strict design standpoint, I realize this might point to having too many actions in a particular controller (otherwise, for example, I could just mark an entire controller as having [Prototype]) , but due to project inertia, I would rather not try to force a change in how actions are placed in controllers.
Currently the autofac registration has the following:
builder.RegisterControllers(Assembly.GetExecutingAssembly());
if (ConfigurationManager.AppSettings["AllowPrototyping"] == "true")
{
builder.RegisterType<PrototypingControllerFactory>().As<IControllerFactory>().InstancePerRequest();
}
However, this means that the controller factory has to do some fancy work to figure out constructor arguments, and get instances from the DI container. Recently, I have discovered some subtle differences in behavior between the custom controller factory, and the "real" controller factory that are not desirable.
I would like to eliminate the custom controller factory, and instead have autofac fully handle resolution of the controllers.
How can I tell autofac to resolve a different implementation of an interface depending on whether the currently executing action is decorated with my custom [Prototype] attribute?
The first option depends on reliably being able to determine the controller action method directly from the route data, which is not necessarily straightforward. Part of the issue is that creation of the controller (and hence injection of the dependencies) occurs fairly early in the process, even before authorization filters run.
If some reliable implementation of a magical method say ActionDescriptor GetActionDescriptor(RoutData routeData) actually existed, then I could do something like the following:
builder.Register<ISomeService>(c =>
{
var httpRequest = c.Resolve<HttpRequestBase>();
var actionDescriptor = GetActionDescriptor(httpRequest.RequestContext.RouteData);
if (actionDescriptor.GetAttributes<PrototypeAttribute>().Any())
{
return new PrototypeSomeService();
}
return new RealSomeService();
}).InstancePerRequest();
However the closest I could come to getting an ActionDescriptor at the point where the controller is intantiated was overriding DefaultControllerFactory, which is precisely what I am trying to get away from.
From default controller factory you can use the protected DefaultControllerFactory.GetControllerType() from which you could then create a ReflectedControllerDescriptor. But then you still have to do some munging to get the correct action descriptor from controllerDescriptor.GetCanonicalActions(). (In fact, I suspect this "munging" is leading to the subtle differences in the original custom controller factory). This could get even more complicated when routes are used from other http handlers (think Elmah or MiniProfiler for example).
In the end I opted to avoid attempting to map RouteData to an ActionDescriptor by making [PrototypeAttribute] inherit from ActionFilterAttribute so that I could easily hook into OnActionExecuting, from which point I added an identifier to the current HttpContext, e.g.
public class PrototypeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Items.Add("Prototype", "Prototype");
base.OnActionExecuting(filterContext);
}
}
Then I modified my PrototypeSomeService so that it wrapped an implementation of ISomeService and delegated to it if the context did not contain the prototype key, e.g.
public class PrototypeSomeService : ISomeService
{
private readonly ISomeService _wrappedService;
private readonly HttpRequestBase _httpRequest;
public PrototypeSomeService(ISomeService wrappedService, HttpRequestBase httpRequest)
{
_wrappedService = wrappedService;
_httpRequest = httpRequest
}
public object SomeMethod()
{
if(_httpRequest.RequestContext.HttpContext.Items.Contains("Prototype"))
return _wrappedService.SomeMethod();
//other prototype logic...
return prototypeResult;
}
}
The final piece to tie it all together is to use autofac's decorator capabilities:
var someServiceRegistration = builder.RegisterType<SomeService>().InstancePerRequest();
if (ConfigurationManager.AppSettings["AllowPrototyping"] == "true")
{
someServiceRegistration.Named<ISomeService>("Prototype");
builder.RegisterDecorator<ISomeService>(
(c, inner) => new PrototypeSomeService(inner, c.Resolve<HttpRequestBase>()),
fromKey: "Prototype"
);
}
else
{
someServiceRegistration.As<ISomeService>();
}
One small downside is that you have to make sure you use a unique key for the httpcontext item or else strange things will happen, but that is pretty easily avoided by e.g. using a guid.
This approach allowed me to leave most of the existing code unchanged, only modifying the prototype implementation of the service and the autofac registrations.
You can read more about autofac decorators at:
http://nblumhardt.com/2011/01/decorator-support-in-autofac-2-4/
http://docs.autofac.org/en/latest/advanced/adapters-decorators.html?highlight=decorator#decorators
I read this question, and the answer helps me but not completely. What if I have 20 repositories with different responsibilities, like for example:
ICountryRepository
ICityRepository
and
IUserRepository
IPersonRepository
I can have all the methods of this repositories in the BaseController, but I would prefer something like having a TerritoriesBaseController, whit the ICoutnryRepository and ICityRepository and PersonsBaseController IUserRepository and IPersonRepository, than inherits from BaseController.7
My problem is that, if I have a controller that wants to use the TerritoryBaseController and PersonBaseController, I can't make it inherit from both controllers.
The reason why I want to separate the base controllers, is for structure, order and for not having a controller with 200 methods, but 20 controllers with 10 methods, and with separated responsibilities.
Some ideas how can it be organized?
EDIT:
I think I didn't explain the question properly.
Let's take this example:
I have a project with IoC, and let's say I have 4 repositories.
ICountryRepository, ICityRepository, IUserRepository, IPersonRepository.
I have a controller that needs methods of the 4 repositories, for example, UserController, it will use IUserRepository and IPersonRepository to save the user, and ICountryRepository and ICityRepository to show a list of countries and cities that the user has to select.
I also have a BaseController, where i have the generic methods of the controllers, and UserController inherits of BaseController, so:
UerController : BaseController
What I would like to do is, have a TerritoriesBaseController, where i would have all the methods that are repeated in my controlers of ICouuntrRepository and ICityRepository, like:
public JsonResult GetCountriesSelectList()
{
List<Country> listCountryLanguage = _applicationCountry.GetAll().ToList();
return Json(new SelectList(listCountryLanguage, "IdCountry", "Name"), JsonRequestBehavior.AllowGet);
}
And the same with IPersonRepository and IUserRepository, with a UserBaseController.
But I Can't use:
Usercontroler : BaseController, TerritoriesBaseController, UserBaseController
Because in c# you can only inherit from one class.
How can i reorganize it or what solution can I use?
What if I have 20 repositories with different responsibilities,
If you have a controller that needs to use 20 repositories, there is something wrong with your design. That controller will violate the Single Responsibility Principle.
There are a few solutions to this problem:
Split the logic in the controller up into multiple smaller, more focused controllers that each have just a few dependencies.
Move part of the logic to an aggregate service. In your case your controller probably has a lots of business logic in it. You should extract that business logic to a different class. The command/handler pattern is very suited for implementing business logic.
If you have code that uses multiple repositories, there's a special well-known pattern that for this: the Unit of Work pattern. What you can do is make those repositories accessible as properties on a Unit of Work class and inject only that unit of work.
UPDATE
UserController, it will use IUserRepository and IPersonRepository to
save the user, and ICountryRepository and ICityRepository to show a
list of countries and cities that the user has to select.
In that case you should extract the logic of saving the user into a new class and you should do the same with the logic for getting the list of countries. In that case your UserController will only depend on two more specific dependencies and the code inside the UserController will be minimized.
Don't use base controllers. Using base classes is often a sign of a glitch in your design. Your code becomes much harder to test when using base classes, and those base classes will often grow into god classes. Besides, you already noticed that multiple inheritance is not possible in .NET.
So what you can do is the following:
public class UserController : Controller
{
private ICommandHandler<SaveUser> saveUserHandler;
private IQueryProcessor queryProcessor;
public UserController(ICommandHandler<SaveUser> saveUserHandler,
IQueryProcessor queryProcessor)
{
this.saveUserHandler = saveUserHandler;
this.queryProcessor = queryProcessor;
}
public ActionResult Save(SaveUserViewModel model)
{
this.saveUserHandler.Handle(new SaveUser
{
UserId = model.UserId,
Name = model.UserName,
});
Redirect("/Success");
}
public JsonResult Countries()
{
var listCountryLanguage = queryProcessor.Execute(new GetAllCountries());
return Json(new SelectList(listCountryLanguage, "IdCountry", "Name"),
JsonRequestBehavior.AllowGet);
}
}
Do note that for this example I use the query/handler and command/handler patterns, but that's optional.
i have just started working in MVC and I have one doubt.
Instead of Nonaction method , we can create private method in controller or we can also write method in model and call that from controller.
So , what is the real purpose to use public NonAction method in MVC ?
(I restructured the answer to better address the questions in the comments)
I think, the attribute is here only for better flexibility. As a framework designer, one wants to relax coding constraints off the end user as much as possible. Requirement of not having public non-actions may sound good "in general" but may be too restrictive for some projects. Adding [NonAction] solves their problem (introduced by their bad design though) - and obviously you're not forced to use the attribute, so it's a win-win from a framework designer perspective.
Another reason may be legacy - in the earlier MVC versions only methods marked with [Action] where considered as actions. So when they relaxed the requirement (and all public methods became treated as actions) they kept [NonAction] so that developers won't get too confused.
In general, using NonAction is a bad practice - exactly for the reasons you stated. If something shouldn't be an action, it should not be public in the first place.
Problem with public non-action methods on the controller is that they make people tempted to instantiate your controller and call the method, instead of separating out the common logic:
Compare
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = new OrdersController().GetOrder(orderId); //GetOrder is public
...
}
}
with
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = _orderService.GetOrder(orderId);
...
}
}
The first approach leads to increased coupling between controllers and non-straightforward code in the actions. Code becomes difficult to follow and refactor, and cumbersome to mock/test.
Besides increased coupling, any public non-action method is a security hole - if you forget to mark it with [NonAction] (or, better, change away from public) - because it's treated as normal action and can be invoked externally. I know the original question kinda implies you surely would never forget to attach the attribute if needed, but it's also kinda important to understand what can happen if you would ;) Oh well, and as we're on this, it seems to me that "forgetting the attribute" is more theoretically probable, comparing to "forgetting to make the method private".
Sometimes people say having public non-actions is necessary for unit testing, but again, when something is not an action it most likely can be isolated in a separate class and tested separately. Moreover, even if it's not feasible for whatever reason, marking a method public for testing purposes only is a bad habit - using internal and InternalsVisibleTo is the recommended way.
This kind of situation may be caused by requirements some testing framework such as you need to do unit testing on that method then you to expose it although its a bad design but can't change these had to bear it out.
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttributeattribute.
Real purpose to use public NonAction
To restrict access to non-action method to notify MVC framework that given controller method is not action.
When you try to run a method with NonAction attribute over URL you get the error 404 as response to request.
Ref: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx
For Detail: http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx
This is beneficial when the Url are not case sensitive. So that for example if you have the request Home/About this goes to HomeController and About action, as well as hOmE/AbOUT is going to the same controller and same action method.
Like below
public class HomeController:Controller
{
....
public ViewResult About()
{
return View();
}
public ViewResult aBOut()
{
return View();
}
}
The framework can’t determine which about function to call, and throws the exception telling that the call is ambiguous.
Of course one way to fix this problem is to change the action name.
If for some reason you don’t want to change the action name, and one of these function is not an action, then you can decorate this non action method with NonAction attribute. Example:
[NonAction]
public ActionResult aBOut()
{
return View();
}
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttribute attribute.
We are using controllers as binding drivers with custom ASP pipeline, each driver is responsible for rendering one section (partial view) of result page. Then we are using public methods like:
[NonAction]
publi int GetOrder()
to resolve sections order on page or other to resolve authorization for current user (e.g. if current section is editable or just read-only).
So you should not restrain yourself to think about Controller as only a way to handle requests but also as a tool to build your custom framework for rendering page. That way we keep our Controllers responsible for exactly one task and we are separating domain concerns.
ASP.NET is highly customizable. Assume you are going to change the default behavior of the framework by overriding the MVC HTTP handler. Maybe you want to customize the logging logic depending on the controller, which is used. Some controllers implement your ILoggingController interface with the method IControllerLogger GetLogger(). For this method you need to write a public non-action method.
I am using MVC3 and have implemented IoC to provide service/manager objects to controllers through constructor arguments. These in turn, may get passed to models.
The problem I am having is that passing these objects all over the place can get cumbersome.
Example:
public CartController(
ICartManager cartManager,
IProductManager productManager,
IUpsellManager upsellManager,
IAccountManager accountManager,
... more ...)
{
... store to class variables ...
}
public ActionResult Index()
{
...
CartModel model = new CartModel(
cartManager,
accountManager,
upsellManager,
productManager,
... );
return View(model);
}
And the cart model may have sub models to which it must pass parameters. As you see, it all gets very cumbersome. I've ready if you have so many constructor arguments, your controller may be doing too much, but this is a complex page, and the site will contain many other complex pages. I don't want to have to pass so many things, but how can I not pass them and maintain a control?
I'm tempted to use the DependencyResolver in the models but that defeats the purpose and Service Locator is known anti-pattern.
How can I avoid passing so many arguments without giving up the benefits of IoC?
The advantage of using dependency inversion is to enforce clear separation of responsibilities between the various roles in the application. The Controller it is really just interested in dealing with HTTP Request and the HTTP Response. All other logic is dealt with elsewhere and the controller delegates to types it is dependent upon to do this work. This pattern is then repeated for each function in the system. One way to detect that this pattern isn't being followed is to use the new operator to create a type and pass in dependencies to the constructor. This is the job for the IoC container you are using.
I would suggest swapping the logic around and having the CartManager return a CartModel for the view. This could be some kind of DTO which is specific to the view. How the data gets put in to this object is the responsibility of the CartManager. If it needs the use of other services they can be injected in to it's constructor.
public CartController : Controller
private ICartManager _cartManager;
public CartController(ICartManager cartManager) {
_cartManager = cartManager;
}
[HttpGet]
public ActionResult Index(int userId) {
var model = _cartManager.CreateCart(int userId);
return View(model);
}
...
public class CartManager : ICartManager {
IDbService _dbService;
public CartManager(IDbService dbService){
_dbService = dbSerivce;
}
CartModel CreateCart(int userId) {
var user = _dbService.FindTheUser(int user);
var cartModel = new CartModel { userId = userId, Name = user.Name };
/* other stuff to map up a cartmodel
return cartModel;
}
}
This idea is not just specific to the use of IoC containers but is also good practice for creating MVC applications. I also found this post by Rob Ashton to be a good guide.
I like using a factory pattern for this scenario, where you need to instantiate class B (CartModel) within class A (CartController), and there are a bunch of dependencies in B that A doesn't need.
public CartController(
ICartModelFactory factory
... more ...)
{
... store to class variables ...
}
public ActionResult Index()
{
...
CartModel model = factory.GetInstance(
... );
return View(model);
}
You shouldn't be passing all those services to your view. What that means is that your template now has to perform actions to call this data, which complicates things (as you've seen). In addition to needless complexity, it also creates a dependency of these services in the view, and tighly couples the view to these services. If you change the services, you then have to change all the views that use it.
First thing you need to do is create a ViewModel that contains all the Data the view will need. Then, you need to find a way to map your manager classes returned data into this view. You can do it manually in the controller, or use something like AutoMapper to do the translations.
Another option is to either refactor ICartManager so that it returns all the data (your CartManager class would then have constructor injection of the other services) or create a different service that aggregates them and constructs an object that you can map to your View model.
You should never have to pass those methods around. They should always be injected into an object.
Let’s say I'm developing a helpdesk application that will be used by multiple departments. Every URL in the application will include a key indicating the specific department. The key will always be the first parameter of every action in the system. For example
http://helpdesk/HR/Members
http://helpdesk/HR/Members/PeterParker
http://helpdesk/HR/Categories
http://helpdesk/Finance/Members
http://helpdesk/Finance/Members/BruceWayne
http://helpdesk/Finance/Categories
The problem is that in each action on each request, I have to take this parameter and then retrieve the Helpdesk Department model from the repository based on that key. From that model I can retrieve the list of members, categories etc., which is different for each Helpdesk Department. This obviously violates DRY.
My question is, how can I create a base controller, which does this for me so that the particular Helpdesk Department specified in the URL is available to all derived controllers, and I can just focus on the actions?
I have a similar scenario in one of my projects, and I'd tend to use a ModelBinder rather than using a separate inheritance hierarchy. You can make a ModelBinder attribute to fetch the entity/entites from the RouteData:
public class HelpdeskDepartmentBinder : CustomModelBinderAttribute, IModelBinder {
public override IModelBinder GetBinder() {
return this;
}
public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
//... extract appropriate value from RouteData and fetch corresponding entity from database.
}
}
...then you can use it to make the HelpdeskDepartment available to all your actions:
public class MyController : Controller {
public ActionResult Index([HelpdeskDepartmentBinder] HelpdeskDepartment department) {
return View();
}
}
Disclaimer: I'm currently running MVC Preview 5, so some of this may be new.
The best-practices way: Just implement a static utility class that provides a method that does the model look-up, taking the RouteData from the action as a parameter. Then, call this method from all actions that require the model.
The kludgy way, for only if every single action in every single controller needs the model, and you really don't want to have an extra method call in your actions: In your Controller-implementing-base-class, override ExecuteCore(), use the RouteData to populate the model, then call the base.ExecuteCore().
You can create a base controller class via normal C# inheritance:
public abstract class BaseController : Controller
{
}
public class DerivedController : BaseController
{
}
You can use this base class only for controllers which require a department. You do not have to do anything special to instantiate a derived controller.
Technically, this works fine. There is some risk from a design point of view, however. If, as you say, all of your controllers will require a department, this is fine. If only some of them will require a department, it might still be fine. But if some controllers require a department, and other controllers require some other inherited behavior, and both subsets intersect, then you could find yourself in a multiple inheritance problem. This would suggest that inheritance would not be the best design to solve your stated problem.