具有路由属性的不明确的控制器名称:具有相同名称和不同名称空间的控制器用于版本控制 [英] Ambiguous Controller Names with Routing attributes: controllers with same name and different namespace for versioning

查看:118
本文介绍了具有路由属性的不明确的控制器名称:具有相同名称和不同名称空间的控制器用于版本控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加API版本控制,我的计划是在不同的命名空间中为每个版本创建一个控制器.我的项目结构如下所示(注意:每个版本都没有单独的区域)

I am trying to add API versioning and my plan is to create a controller for each version in different namespace. My project structure looks like this (note: no separate area for each version)

Controllers
 |
 |---Version0
 |      |
 |      |----- ProjectController.cs
 |      |----- HomeController.cs
 |
 |---Version1
       |
       |----- ProjectController.cs
       |----- HomeController.cs

我正在为路由使用RoutingAttribute. 因此,Version0中的ProjectController具有路由为

I am using RoutingAttribute for the routes. So, ProjectController in Version0 has function with route as

namespace MyProject.Controllers.Version0
{
   class ProjectController : BaseController
   {
     ...

     [Route(api/users/project/getProjects/{projectId})]
     public async GetProjects(string projectId) 
     {
       ...
     }
  }
}

和Version1中的ProjectController具有路由为

and ProjectController in Version1 has function with route as

namespace MyProject.Controllers.Version1
{
   class ProjectController : BaseController
   {
     ...

     [Route(api/v1/users/project/getProjects/{projectId})]
     public async GetProjects(string projectId) 
     {
      ...
     }
  }
}

但是,当我尝试使用该服务时会收到404-NotFound.

But, I get 404-NotFound when I am trying to hit the service.

如果我将控制器重命名为唯一名称(Project1Controller和Project2Controller),则路由工作.但是,我试图避免为了简单而重命名.

If I rename the controllers to have unique name (Project1Controller and Project2Controller) the routing works. But, I am trying to avoid renaming for simplicity.

我点击了此链接以解决此问题,但没有帮助.我确实创造了领域,但仍然没有成功.在global.aspx文件中添加路由逻辑无济于事.命名空间也不起作用. http://haacked.com/archive/2010/01/12/ambiguous-controller -names.aspx/

I followed this link to resolve the issue, but it didn't help. I did create areas but still no success. Adding routing logic in global.aspx file do not help. The namespace do not work either. http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx/

上面的链接建议创建区域,但是根据该链接,属性路由不支持区域: http://www. asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

The above link suggest to create areas, but the attribute routing do not support areas as per link: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

还有其他解决方案吗?带有RoutingAttributes的错误?

Is there another solution? A bug with RoutingAttributes?

谢谢!

推荐答案

首先,Web API路由和MVC路由不能以完全相同的方式工作.

First, Web API routing, and MVC routing doesn't work exactly in the same way.

您的第一个链接指向带有区域的MVC路由.虽然您可以尝试制作与它们相似的内容,但是官方不支持Web API的区域.但是,即使尝试执行类似的操作,也会遇到相同的错误,因为在Web API中查找控制器的方式并未考虑到控制器的名称空间.

Your first link points to MVC routing, with areas. Areas are not officially supported for Web API, although you can try to make something similar to them. However, even if you try to do something like that, you'll get the same error, because the way in wich Web API looks for a controller doesn't takes into account the controller's namespace.

因此,开箱即用将永远无法使用.

So, out of the box, it will never work.

但是,您可以修改大多数Web API行为,这也不例外.

However, you can modify most Web API behaviors, and this is not an exception.

Web API使用控制器选择器来获取所需的控制器.上面说明的行为是 DefaultHttpControllerSelector (随Web API一起提供),但是您可以实现自己的选择器来替换默认选择器,并支持新行为.

Web API uses a Controller Selector to get the desired controller. The behavior explained above is the behavior of the DefaultHttpControllerSelector, which comes with Web API, but you can implement your own selector to replace the default one, and support new behaviors.

如果您用Google搜索自定义Web API控制器选择器",则会发现很多示例,但对于您的问题,我发现这最有趣:

If you google for "custom web api controller selector" you'll find many samples, but I find this the most interesting for exactly your problem:

此实现也很有趣:

  • https://github.com/WebApiContrib/WebAPIContrib/pull/111/files (thank you to Robin van der Knaap for the update of this broken link)

如您所见,基本上,您需要:

As you see there, basically you need to:

  • 实现您自己的IHttpControllerSelector,该过程将考虑名称空间以找到控制器,并考虑名称空间的路由变量,以选择其中的一个.
  • 通过Web API配置以此替换原始选择器.
  • implement your own IHttpControllerSelector, which takes into account namespaces to find the controllers, and the namespaces route variable, to choose one of them.
  • replace the original selector with this via Web API configuration.

这篇关于具有路由属性的不明确的控制器名称:具有相同名称和不同名称空间的控制器用于版本控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆