实现涉及多个程序集的自定义控制器工厂

时间:2015-01-19 21:35:03

标签: c# asp.net-mvc model-view-controller controller controller-factory

目前,我们正在尝试在API中实现自定义控制器工厂,以确定要使用的正确控制器,具体取决于传入API的标识符令牌。这个项目的设置方式是每个不同的公司(只有大约5个)都有自己的程序集,其中包含自定义控制器,这些控制器具有执行某人试图执行的任何操作所需的操作方法。我发送的要求之一是控制器必须在这些程序集中命名相同。例如,您可以拥有四个不同的控制器,每个控制器位于一个名为CustomerController的不同程序集中。这四个控制器都包含同样命名的Action方法,但它们中的实现完全不同。

当使用我们的自定义控制器工厂时,我们使用Reflection来拉取并创建一个正确的控制器类型的实例,该实例应该针对哪个程序集。我已对此进行了调试,并确认正在返回正确的Controller。

在Action Method调用期间发生问题。即使我们的控制器工厂正在为我们的请求返回正确的控制器,似乎MVC可能预装了这些组件中的每个控制器,并且仍然将这些作为可能的方向。我们在调用Action方法时遇到的确切错误是:The current request is ambiguous between the following action methods

有没有办法告诉MVC忽略控制器工厂请求中未返回的其他控制器,这样它就会知道不会试图查看其他似乎没有加载的控制器?如果MVC只是要检查所有其他控制器的Action Method匹配,那么ControllerFactory有什么意义呢?我必须在这里找到一些东西。

我发现解决此问题的唯一其他解决方案是向所涉及的所有操作方法添加ActionMethodSelector属性。然而,这使得解决方案在展望未来时非常脆弱,并且考虑到每个Action Action都需要在它们之间重复相同的属性。

期待任何有关MVC行为方式的建议或知识,当我实现了一个自定义控制器工厂时,应该决定选择哪个控制器来使用操作方法。提前谢谢!

1 个答案:

答案 0 :(得分:1)

我们找到了解决方案。控制器工厂按预期工作。问题实际上在我们的路由中。在实现此解决方案之前,我们已使用Route属性标记了Action Methods。因此,例如,对于我们拥有的不同组件中的每个控制器

[Route("Customer/Lookup/{name}")] public ActionResult LookupByName(string name) { // Custom code content here }

事实证明,在这些ActionMethods上指定​​Route属性优先于所选控制器,并且无论如何都会调用与当前请求的控制器/操作匹配的所有控制器。我们的解决方案是删除此属性并将RouteConfig.cs文件中所需的内容放入其中,以便动态加载它,并将完全控制权返回给我们的自定义控制器工厂,以决定专门用于所选ActionMethod的Controller。

routes.MapRoute( name: "CustomerLookup", url: "customer/lookup/{name}", defaults: new { controller = "Customer", action = "LookupByName", name = UrlParameter.Optional } );