带有MVC的ASP.NET Web API:类库中忽略的属性路由

时间:2014-08-31 11:33:32

标签: asp.net-mvc asp.net-web-api asp.net-web-api2

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

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

浏览到/ api / cms / test时,出现以下错误:

“找不到与请求URI匹配的HTTP资源'[我的网站]:30863 / api / cms / test'。找不到与名为'cms'的控制器匹配的类型。”

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

我在System.Web.Http.GlobalConfiguration.Configuration.Routes检查了路线收集,并确认路线确实缺失。

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

修改

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

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

这个问题是现在DataTokens为空且只读!因此,它不再是解决这个问题的可行方案。希望别人能解决这个问题。

编辑2

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

因此,我需要做很多工作才能完成所需的工作;如果它甚至可能。我将开始赏金;对于能够提供完整解决方案或能够为我提供足够信息以便自己开始解决方案的人来说,100分。

1 个答案:

答案 0 :(得分:2)

从错误消息看,路由的顺序看起来不正确...看起来您的请求正在被传统路由匹配(例如:api/{controller})而不是属性路由......就像您一样知道路线顺序很重要...所以确保在常规路线之前注册属性路线,因为它们更具体......

另请注意,仅RoutePrefix属性不会将路由添加到路由表,但属性Route会... ...

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