3

我最初的问题是我正在寻找在 Restful API 中进行版本控制的最佳实践。没有多少人谈论这个,没有一个好的答案,或者我目前无法找到确切的解决方案。

(1) 起初我想为每个版本Tag使用http://domain.com/API/ {version}。因此,如果发布了新的 API,我会将其导出并发布到相应的 URL,但似乎很难在一个 Web 应用程序中混合不同版本的源代码。BranchTag

(2) 然后我想用这种方式,一个版本一个控制器:(就像这个问题Versioning of REST API Built With ASP.NET MVC 3 - Best Practices

http://domain.com/API/1.0/{AnAction} => will go to APIV1Controller.{AnAction}

http://domain.com/API/2.0/{AnAction} => will go to APIV2Controller.{AnAction}

但它需要为每个版本编写一个路由。

(3) 第三种方法是我从 PayPal API 获得的想法,即版本不在 URL 中,而是在 POST 参数中。所以 URL 固定为http://domain.com/API/但用户必须指定Version参数有"1.0"or "2.0"

解决方案:(2)对我来说没问题,目前我使用这种方式,但我想混合(2)和(3)所以我有一个 APIController,它只有一个索引操作来检查这个Version参数并传输对相应控制器的请求和操作 APIV1Controller.{AnAction} 或 APIV2Controller.{AnAction}。

在谷歌搜索和 Stackoverflowing 关于如何在没有重定向的情况下传输、调用或调用另一个控制器和操作之后。似乎没有好的答案和好的做法。有人通过简单地创建控制器的新实例来回答不同控制器上的 .NET MVC 调用方法。突然间我想到了怎么办reroute

问题:

是否可以reroute在没有重定向的情况下对另一个控制器和另一个动作执行动作以及如何做到这一点?

或者一个特定的问题,当用户请求http://domain.com/API/{AnAction}Version="2.0",我该如何rerouteAPIController.Indexto APIV2Controller.{AnAction}

我没有使用 IoC。

4

2 回答 2

1

这可以通过路由约束来完成。首先实现IRouteConstraint

public class RequestParameterConstraint : IRouteConstraint
{
    public string ParameterName { get; private set; }
    public string ParameterValue { get; private set; }

    public RequestParameterConstraint(string parameter, string value)
    {
        ParameterName = parameter;
        ParameterValue = value;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName,
        RouteValueDictionary values, RouteDirection routeDirection)
    {
        var value = httpContext.Request[ParameterName] ?? "";
        return value.Equals(ParameterValue);
    }
}

然后注册路由:

routes.MapRoute(
    "Version10",
    "API/{action}/{id}",
    new { controller = "APIV1", action = "Index", id = UrlParameter.Optional },
    new { header = new RequestParameterConstraint("Version", "1.0") }
    );

routes.MapRoute(
    "Version20",
    "API/{action}/{id}",
    new { controller = "APIV2", action = "Index", id = UrlParameter.Optional },
    new { header = new RequestParameterConstraint("Version", "2.0") }
    );

就这样。这会成功的。

于 2013-11-05T18:21:18.167 回答
0

http://coderjournal.com/2010/09/simple-rest-api-versioning-using-mef-and-mvc/

这似乎完全符合您的要求,但是通过使用一组完全不同的控制器,而不是重新路由到它们,它采用了一种非常不同的方法。

希望这可以帮助。

于 2011-05-12T18:56:24.483 回答