代码之家  ›  专栏  ›  技术社区  ›  Aaron Palmer

在ASP.NET MVC中,是否可以生成通用控制器?

  •  27
  • Aaron Palmer  · 技术社区  · 17 年前

    我正在尝试创建一个通用控制器,即:

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

    但是,当我尝试使用它时,我在任何地方都会遇到这个错误…

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

    所以,我的问题是,是否可以在ASP.NET MVC中生成一个通用控制器?

    谢谢!

    5 回复  |  直到 8 年前
        1
  •  37
  •   Jim Wolff    10 年前

    如果我正确理解您,那么您要做的就是通过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;
    }
    
        2
  •  9
  •   Iain Holder    17 年前

    是的,你可以,很好,我自己也经常用。

    您需要确保的是,当您从MyController继承时,您仍然以Controller结束类型名:

    public class FooController :  MyController<Foo>
    { 
     ...
    }
    
        3
  •  1
  •   Martin Peck    17 年前

    当默认的控制器工厂试图找到一个控制器来发送请求时,它在控制器名称周围使用“约定”。如果需要,您可以重写这个查找功能,这样就可以让通用控制器工作。

    这篇文章…

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

    …对所发生的事情有一个很好的描述。

        4
  •  1
  •   Community Mohan Dere    9 年前

    这是的副本 asp.net mvc generic controller 它实际上包含了正确的答案。杰夫·弗里茨的回答绝对不正确。创建自己的IControllerFactory不会超过ExpressionHelper.GetRouteValuesFromExpression中的限制,因为它会生成您看到的错误。无论何时调用RedirectToAction、BuildUrlFromExpression、ActionLink、renderAction、BegInform或任何调用这些方法,实现自己的IControllerFactory都会给您留下错误。

    我感兴趣的是,Microsoft的“约定限制”已经由expressionHelper.getRouteValuesFromExpression方法中的类型上放置的约束“where tcontroller:controller”强制实施。没有通用的将永远满足约定验证:

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

    除非它被以“controller”结尾的类继承,因为typeof(anygeneric).name永远不会以“controller”结尾。

        5
  •  0
  •   Matt Kocaj    17 年前

    如果我是你,我会得到 MVC source 并使用源代码创建一个测试MVC项目,这样您就可以检查在何处生成异常,并了解如何处理您的通用思想和强制的“*控制器”命名约定。