2014-08-31 126 views
0

我正在开发一个使用插件的MVC应用程序。我需要支持从这些插件使用Web API。我有它的工作(包括与Autofac的依赖注入以及)。但是,似乎属性路由从类库(插件或任何其他程序集)中完全忽略。例如,我有指定为这样的测试插件:MVC中的ASP.NET Web API:类库中忽略的属性路由

[RoutePrefix("api/cms/test")] 
    public class TestController : ApiController 
    { 

当浏览到/ API/CMS /测试,我得到以下错误:

“没有HTTP资源发现,请求匹配URI'[我的网站]:30863/api/cms/test'.No类型被找到匹配名为'cms'的控制器。“

当我删除“cms”时,它工作,因为它然后使用默认路由。显然,这是不够的,因为我很可能会有多个具有相同名称的控制器(在不同的程序集中),因此需要一条到它们每个的唯一路径。

我检查了路线收集System.Web.Http.GlobalConfiguration.Configuration.Routes以及确认和路线确实缺失。

有没有人能告诉我为什么属性路由被忽略的类库以及是否有解决方法?

编辑

感谢基兰有关路由属性的注释;我确实注意到我的错误,忘记了控制器上的[Route("")]属性,该属性将与[RoutePrefix]属性一起使用。我补充说,现在属性路由工作正常。但是,即使它们位于不同的程序集中,我仍然不能拥有2个具有相同名称的控制器。在做了一些研究之后,似乎这是一个已知问题 - 不仅仅是使用不同的程序集,而是一般的不同名称空间。我试图从这里实现一个解决方案:

http://shazwazza.com/post/multiple-webapi-controllers-with-the-same-name-but-different-namespaces/

这样做的问题是,现在DataTokens为空和只读!所以它不再是这个问题的可行解决方案。希望别人解决这个问题。

EDIT 2

感谢基兰为他约路由约束提。但是,这仍然不能解决我的问题。我在寻找的是一种允许多个控制器具有相同名称的方法,无论它们位于单独的区域,单独的命名空间还是两者都有。无论如何。问题在于底层Web API实现通过名称查找控制器一个IDictionary<string, HttpControllerDescriptor>变量来存储这样的信息。如果您查看DefaultHttpControllerSelector的源代码,您可以看到这一点。所以,起初我想也许我只需要继承这个类并覆盖GetControllerMapping(),因为内部类AttributeRoutingMapper中的调用代码根本不关心该字典中的键......它只查看值。所以起初我以为我可以覆盖它并使用控制器的全名(包括名称空间)作为关键字,所以我们可以将它们全部放在那里。然而,这并不是那么容易..出于几个原因,其中至少有一个事实是AttributeRoutingMapper并不是唯一称为GetControllerMapping()的类。

因此,看起来要做很多工作才能获得我所需要的;如果它甚至可能。我将开始赏金; 100分给任何能够提供完整工作解决方案的人,或者可以提供足够信息让我自己开始解决方案的人。

回答

2

从错误消息看,路线顺序看起来不正确......看起来您的请求正在与传统路线(例如:api/{controller})匹配,而不是属性路线......如您所知路线顺序因此请务必在常规路由之前注册属性路由,因为它们更具体...

另请注意,单独的RoutePrefix属性不会将路由添加到路由表,但属性Route会影响路由。 。

我猜你在托管你的应用程序在IIS?

+0

+1关于'[路线]'的说明。谢谢。请参阅我上面的编辑。 – Matt 2014-09-01 00:17:17

+0

一般来说,Web API本身不支持跨名称空间的相同控制器名称......您需要为您的控制器使用不同的名称......使用此方法的示例:http://aspnet.codeplex.com/SourceControl/最新的#Samples/WebApi/RoutingConstraintsSample/ReadMe.txt – 2014-09-01 00:44:14

+0

谢谢,Kiran。这个问题并没有真正使Web API成为一个不错的可插拔体系结构,尽管...我将查看您发送的链接,看看是否有任何定制可以解决此问题。谢谢。 – Matt 2014-09-01 12:56:27