In asp.net mvc is it possible to make a generic controller?

I’m attempting to create a generic controller, ie:

public class MyController<T> : Controller where T : SomeType
{ ... }

However, when I try to use it, I’m running into this error everywhere…

Controller name must end in ‘Controller’

So, my question, Is it possible to make a generic controller in asp.net mvc?

Thanks!

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

If I understand you properly, what you are trying to do, is route all requests for a given Model through a generic controller of type T.

You would like the T to vary based on the Model requested.

You would like /Product/Index to trigger MyController<Product>.Index()

This can be accomplished by writing your own IControllerFactory and implementing the CreateController method like this:

public IController CreateController(RequestContext requestContext, string controllerName)
{
    Type controllerType = Type.GetType("MyController")
                              .MakeGenericType(Type.GetType(controllerName));
    return Activator.CreateInstance(controllerType) as IController;
}

Solution 2

Yes you can, it’s fine and I’ve used them lots myself.

What you need to ensure is that when you inherit from MyController you still end the type name with controller:

public class FooController :  MyController<Foo>
{ 
 ...
}

Solution 3

The default controller factory uses “convention” around controller names when it’s trying to find a controller to dispatch the request to. You could override this lookup functionality if you wanted, which could then allow your generic controller to work.

This MSDN article…

http://msdn.microsoft.com/en-us/magazine/dd695917.aspx

… has a good writeup of what’s going on.

Solution 4

This is a duplicate of asp.net mvc generic controller which actually contains the correct answer. Jeff Fritz’s answer is absolutely not correct. Creating your own IControllerFactory will not get past the limitation in ExpressionHelper.GetRouteValuesFromExpression which is generating the error you are seeing. Implementing your own IControllerFactory will still leave you with errors whenever you call RedirectToAction, BuildUrlFromExpression, ActionLink, RenderAction, BeginForm, any any methods that call those.

What is interesting to me, is that Microsoft’s “restriction by convention” is already enforced by the constraint “where TController : Controller” that is placed upon the type in the ExpressionHelper.GetRouteValuesFromExpression method. No generic will ever satisfy the convention validation:

string controllerName = typeof(TController).Name;
if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
    throw new ArgumentException(MvcResources.ExpressionHelper_TargetMustEndInController, "action");
}

unless it is inherited by a class ending in “Controller” because typeof(AnyGeneric).Name will never end with “Controller”.

Solution 5

If i was you, i’d get the MVC source and create a test MVC project with the source code so you can examine where the exception is generated and see what you can do about your generic idea and the enforced “*controller” naming convention.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply