在asp.net mvc有可能使一个通用的控制器?

我试图创build一个通用控制器,即:

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

但是,当我尝试使用它时,我遇到了这个错误…

控制器名称必须以“控制器”结尾

所以,我的问题是否有可能在asp.net mvc中制作一个通用控制器?

谢谢!

如果我正确地理解了你,你想要做的是通过一个T型的通用控制器路由给定模型的所有请求。

您希望T根据所要求的型号而有所不同。

您希望/Product/Index触发MyController<Product>.Index()

这可以通过编写您自己的IControllerFactory并实现像这样的CreateController方法来实现:

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

是的,你可以,没关系,我自己也用了很多。

你需要确保的是,当你从MyControllerinheritance你仍然结束控制器的types名称:

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

当控制器工厂试图find控制器来分派请求时,默认的控制器工厂在控制器名称周围使用“约定”。 你可以重写这个查找function,如果你想,这可以让你的通用控制器工作。

这个MSDN文章…

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

对发生的事情有很好的logging。

这是实际包含正确答案的asp.net mvc通用控制器的副本。 杰夫·弗里茨的答案是绝对不正确的。 创build您自己的IControllerFactory不会超过ExpressionHelper.GetRouteValuesFromExpression中的限制,这会产生您所看到的错误。 无论何时调用RedirectToAction,BuildUrlFromExpression,ActionLink,RenderAction,BeginForm,以及任何调用这些方法的方法,实现自己的IControllerFactory仍然会导致错误。

我感兴趣的是微软的“约定约束”已经被放置在ExpressionHelper.GetRouteValuesFromExpression方法的types中的“where TController:Controller”约束已经被强制执行。 没有通用的方法可以满足公约的validation:

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

除非它由以“Controller”结尾的类inheritance,因为typeof(AnyGeneric).Name永远不会以“Controller”结尾。

如果我是你,我会得到MVC源代码,并用源代码创build一个testingMVC项目,这样你就可以检查exception产生的地方,看看你可以做什么关于你的通用想法和强制的“*控制器”命名约定。