En asp.net mvc, ¿es posible hacer un controlador genérico?

Estoy intentando crear un controlador genérico, es decir:

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

Sin embargo, cuando trato de usarlo, me encuentro con este error en todas partes …

El nombre del controlador debe terminar en ‘Controlador’

Entonces, mi pregunta, ¿es posible hacer un controlador genérico en asp.net mvc?

¡Gracias!

Si lo entiendo correctamente, lo que está tratando de hacer es encaminar todas las solicitudes para un Modelo dado a través de un controlador genérico de tipo T.

Le gustaría que la T varíe según el Modelo solicitado.

MyController.Index() /Product/Index active MyController.Index()

Esto se puede lograr escribiendo su propia IControllerFactory e implementando el método CreateController esta manera:

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

Sí, puedes, está bien y yo mismo los he usado mucho.

Lo que necesita asegurarse es que cuando herede de MyController aún termine el nombre del tipo con el controlador:

 public class FooController : MyController { ... } 

La fábrica de controladores predeterminada usa “convenciones” con los nombres de los controladores cuando intenta encontrar un controlador para enviar la solicitud. Puede anular esta funcionalidad de búsqueda si lo desea, lo que podría permitir que su controlador genérico funcione.

Este artículo de MSDN …

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

… tiene una buena descripción de lo que está pasando.

Este es un duplicado del controlador genérico asp.net mvc que en realidad contiene la respuesta correcta. La respuesta de Jeff Fritz es absolutamente incorrecta. La creación de su propio IControllerFactory no superará la limitación de ExpressionHelper.GetRouteValuesFromExpression que está generando el error que está viendo. La implementación de su propia IControllerFactory aún le dejará errores cada vez que llame a RedirectToAction, BuildUrlFromExpression, ActionLink, RenderAction, BeginForm, a cualquier método que los llame.

Lo que es interesante para mí, es que la “restricción por convención” de Microsoft ya está impuesta por la restricción “donde TController: Controller” que se coloca sobre el tipo en el método ExpressionHelper.GetRouteValuesFromExpression. Ningún genérico alguna vez satisfará la validación de la convención:

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

a menos que sea heredado por una clase que termine en “Controlador” porque typeof (AnyGeneric) .Name nunca terminará con “Controlador”.

Si yo fuera tú, obtendría la fuente MVC y crearía un proyecto MVC de prueba con el código fuente para que puedas examinar dónde se genera la excepción y ver qué puedes hacer con tu idea genérica y la convención de nomenclatura “* controller” forzada .