9

我有一个 ASP.NET MVC 4 应用程序。我想将新的 Web API 功能用于学习目的。我想学习如何公开相同的端点,但提供不同的版本。换句话说,我想公开如下端点:

http://mysite/1.0/Products/1
http://mysite/2.0/Products/1

为了尝试做到这一点,我在默认的“Controllers”目录中添加了一个“Api”目录。在“Api”目录中,我还有另外两个目录:“Version1-0”和“Version2-0”。这些目录中的每一个都有一个名为“ProductsController”的 ApiController。

我试图通过在我的 WebApiConfig.cs 文件中添加以下路由定义来公开端点:

config.Routes.MapHttpRoute(
  name: "1-0Api",
  routeTemplate: "api/1.0/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);

不幸的是,我不知道如何通过上面列出的 URL 公开操作。我究竟做错了什么?谢谢!

4

5 回答 5

7

您可能会遇到问题,因为控制器具有相同的名称。控制器命名空间或它所在的文件夹对 WebAPI 来说根本不重要,只有名称才重要。我能想到的最简单的事情是重命名您的控制器 ProductsV1Controller 和 ProductsV2Controller 并设置两条路由指向您的控制器:

config.Routes.MapHttpRoute(
    name: "1-0Api",
    routeTemplate: "api/1.0/Products/{id}",
    defaults: new { controller = "ProductsV1", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "2-0Api",
    routeTemplate: "api/2.0/Products/{id}",
    defaults: new { controller = "ProductsV2", id = RouteParameter.Optional }
);

当然,如果您想以这种方式公开多个控制器,这会变得很混乱。让我看看我能不能想出更好的东西给你。

于 2012-12-21T01:28:52.593 回答
5

Sebastiaan Dammann 在他的博客中描述了他如何通过编写自己的实现IHttpControllerSelector和支持接口来进行 Web API 版本控制。

http://damsteen.nl/blog/implementing-versioning-in-asp.net-web-api

他还把代码放在了github上

https://github.com/Sebazzz/SDammann.WebApi.Versioning

并为我们将其打包在 NuGet 中!:)

https://nuget.org/packages/SDammann.WebApi.Versioning

虽然实现IHttpControllerSelector肯定是(恕我直言)进行 Web API 版本控制的正确方法,但我认为如果他包括基于 HTTPAccept标头的版本能力将是理想的(参见http://barelyenough.org/blog/2008/05/版本控制-rest-web-services/)。

不幸的是,我的客户端无法使用Accept标头,所以他RouteVersionedControllerSelector对我来说是理想的。

编辑:不知道我是怎么错过的,但确实有一个AcceptHeaderVersionedControllerSelector可以用来做版本控制的理想方式。我目前正在一个新项目中使用它,但它仍然有一些缺点

于 2013-02-26T16:41:24.910 回答
1

在使用 URL 的 Web Api 2 中使用 HttpControllerSelctor 实现控制器版本控制

有关更多信息,您可以查看这里

于 2015-04-05T19:42:45.640 回答
1

您是否仍然定义了默认的 Web API 路由并且它您的自定义路由之前?这将导致您的方案失败。以下路线定义(注意顺序)对我有用。

public static void Register(HttpConfiguration config) {
    config.Routes.MapHttpRoute(
        name: "1-0Api",
        routeTemplate: "api/1.0/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}
于 2012-12-27T18:47:46.753 回答
0

如果我们采用您的第一种方法,那么它有助于路由并允许我们获取 V1、V2 的数据......但现在我们为一个控制器提供了 v1 和 v2 的示例,因此路由代码如下:

config.Routes.MapHttpRoute(
    name: "1-0Api",
    routeTemplate: "tables/v1/Products",
    defaults: new { controller = "ProductsV1", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "2-0Api",
    routeTemplate: "tables/v2/Products",
    defaults: new { controller = "ProductsV2", id = RouteParameter.Optional }
);

但是我们有 20 多个控制器和多个版本,然后如何使其通用。

于 2017-11-03T06:45:12.583 回答