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

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

问题描述

我正在尝试添加 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) 
     {
       ...
     }
  }
}

和版本1中的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

还有其他解决方案吗?路由属性的错误?

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天全站免登陆