ASP.NET MVC controllers static methods - asp.net-mvc

A discussion came up at work recently about why ASP.NET MVC doesn't use static methods for its controller methods. Whilst I was on the side of the fence against using static methods, the only two arguments I could think for non-static action methods were inheritence and the ability to mock (which inheritence gives you).
What was Microsoft's design choice for non-static actions/methods over static?

While I don't know minds of those that designed the ASP.NET MVC Framework here is the big one for me:
An instance controller is instantiated once per request, multiple requests can be happening simultaneously. If a controller is static then any state on the controller is shared across all requests simultaneously. You probably don't want that. Updating that shared state becomes a minefield of locking contention, possible deadlocks and very hard to track bugs if locking isn't implemented properly.
In short, a static controller would be a nightmare to work with.

You have for example controller "Home" and action "FillData",
and another controller "Student" and action "FillData".
Imagine what will happen if you make action "FillData" a static method, and could be called in any other controller easily.
It would be a big ISSUE.

Related

Base Controller method or Utility helper method

On my MVC app, I am planning to create a generic method for Web Api's. This can be achieved either creating methods on Base Controller or methods in Utility helper class. Which is preferred way Base controller (or) Utility Class?
And also want to know on what scenario's Base Controller is useful.
ASP.NET MVC provides several alternatives to common problems (e.g. logging, exception handling, authorization) using filters or allowing your own implementation of a certain class. Usually a base controller is not the best approach since it is very likely the framework already handles the issue by other means.
Take a look at this answer for how to deal with common problems in ASP.NET MVC: https://stackoverflow.com/a/6119341/1942895

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).

asp.net mvc is it proper to create an instance of a controller in another controller's constructor?

i have several controllers which will all be using common functionality. So i have separated that functionality into a separate controller.
the shared controller needs a parameter specific to which controller it is being used from, and needs to return views based on id ints passed to it.
So, one idea is to create an instance of SharedController(int callingControllerId) in the constructor of each of the controllers that will be using it. Then, within the action methods of each controller, call the action methods of the shared controller, passing appropriate ids, and returning views from SharedController to the calling controller, which would return the view to be rendered.
Does this sound right? Should controllers be creating other controllers in MVC?
Thanks!
Absolutely not although having your controller inherit from a shared, base controller is pretty common.
public KittyController : MySharedBaseController
{
}
Like Greg Roberts points out that although having a ControllerBase is common it is not always the best place to store shared functionality. MVC has a lot of extensibility points and picking a narrow place to wedge in your code is a lot better than smushing tons of things into a base controller.
I would agree that a base controller is pretty common, but I'm not sure it's the right solution for what you are describing.
Without knowing what is exactly shared it's a bit hard to figure out, but the whole bit of your base controller knowing specifics about the controllers that are inheriting from it smells a bit.
Here are a couple things to consider.
Composition is almost always better than inheritance. Great article on this
Base controller should have common methods/properties, for example mine have some properties of getting the current user and a generic method for calling external services, but not specific things from inheriting controllers. Rule of thumb, if it's not needed by more than 1 controller, than probably not good in base implementation.
It's possible that some of the new MVC 2 features might solve what you are doing. Look at render action.
As with anything in software, there are tons of ways to solve the problem, so ultimately do it the way that makes the most sense to you and your team.
Controllers are constructed by the ASP.NET MVC runtime and you should never be constructing them in your own code. It sounds like you don't really need a separate controller, you just need another class that you aggregate in the controller, and use as a service. This is perfectly acceptable. In fact, I would go so far as to say that in general controller should be delegating their work to other "service" classes and shouldn't have much responsibility (especially domain logic) in and of themselves.
I don't know the details of why this service class needs to know what controller it is being called from, but perhaps you can just declare an enum that defines the different use cases, and pass that in in its constructor. Actually having the service class know about different controllers would be a code smell for me.

Why is there no internal Controller redirect in ASP.Net MVC (or CodeIgniter)?

ASP.Net MVC Controllers have several methods of forwarding control to another controller or action. However, all of them cause a client redirect, with a 302 and a new browser request.
Why is there no internal "call another controller's action" functionality, without getting the client involved? I'm pretty sure that the php CodeIgniter framework also lacks this functionality.
The best reason that I can come up with is that ultimately it's unnecessary, since any code you want to call into could be factored out into someplace common, and in ASP.Net MVC at least, the operation might be quite expensive. But a lot of people ask about this, and it seems like it would ultimately be a convenience.
So... lots of smart people designed these frameworks. There must be some good reasons for not having this?
In Codeigniter you can set custom routes and stuff to direct certain URLs to other controllers/actions, but I think you mean in the middle of a controller function to jump into another?
If there is any business logic you have, especially if it's going to be reused, it should go into a model, not a controller. You can also specify different views in a controller depending on some condition or something. If you have repeating code that doesn't 'fit' into a model, then it should probably end up as a static helper function, or in a library class.
So yeah, I think you're right on when you say:
The best reason that I can come up with is that ultimately it's unnecessary, since any code you want to call into could be factored out into someplace common
This forces you into staying within the MVC pattern.
Best to keep your controllers lightweight anyways.
Well, at least in ASP.NET MVC, controller actions are just C# methods called in creative ways. So you can just explicitly call another controller action, like so:
Sample controller:
public class SampleController : Controller
{
public ActionResult Foo()
{
return View("foo");
}
public ActionResult ShowMeFoo()
{
return Foo();
}
}
Now, I think in most cases one wouldn't want to do this. Considering urls as a RPC interface for your app, it should forward to a different url when getting different results. Doesn't apply to all cases, but can appy to most.
I suspect it may go against the REST idea, everything is a resource. If you wish to perform a server transfer, you can as well offer an extra url for that resource. This way the client will know on that specific url he will receive one particular representation of a resource, and not under circumstances something else. That makes sense actually.

Policy Injection with ASP.NET MVC Controllers

I'm running into an issue with the Policy Injection Application Block from Enterprise Library in conjunction with ASP.NET MVC.
In my ControllerFactory, I'm creating the controller and then calling PolicyInjection.Wrap on the controller. This gives me back a Transparent Proxy to the controller which manages the call handler chain.
Finally, I cast the Transparent Proxy to an IController and return it.
This seems to work well, except that none of the call handlers I've defined for my controller are executing. (For example I have a Logging Handler configured, but nothing is being logged by PIAB.)
Is my final cast messing this up somehow? How does ControllerBase.Execute() call into my controller? It seems like my proxy should be utilized. Anyone using PIAB on ASP.NET controllers?
I am using PIAB to wrap ASP.NET MVC Controllers, and I'm doing so by calling
PolicyInjection.Wrap<IController>(instance)
which will wrap the IController methods. I'm also using policy injection to wrap the IActionInvoker that gets used as well, which allows for logging the action name.
I have not had success wrapping controllers using the MarshalByRefObject wrapping, but the interface wrapping works like a charm.
If you want additional information, you could create an interface that has all the methods from IController, IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter and then have your controllers implement that interface. Then you could wrap your controllers as that interface and get more calls going through policy injection.
I hope that helps. If you have more specific issues please post.
Seems at least one person uses it :) - ASP.NET MVC Validation using Policy Injection Application Block in Enterprise Library (this is first result BTW)

Resources