我原来的问题是我在寻找在Restful API中进行版本控制的最佳做法。没有多少人谈论这个,没有一个好的答案,或者我现在无法找到确切的解决方案。
(1)首先,我打算对每个版本http://domain.com/API/ {version}使用Tag
或Branch
。因此,如果新的API发布,我Tag
,导出并发布到相应的URL,但似乎很难在一个Web应用程序中混合使用不同版本的源。
(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参数中。因此,网址已固定为http://domain.com/API/
,但用户必须指定Version
参数才能"1.0"
或"2.0"
。
对此的解决方案:(2)对我来说没问题,目前我使用这种方式,但我想混合(2)和(3)所以我有一个APIController只有一个Index动作来检查这个Version
参数并将请求传输到相应的控制器和操作APIV1Controller。{AnAction}或APIV2Controller。{AnAction}。
在谷歌搜索和Stackoverflowing之后关于如何传输,调用或调用另一个控制器和操作而无需重定向。似乎没有好的答案和良好的做法。有人通过简单地创建控制器的新实例来回答.NET MVC Call method on different controller。突然间,我明白了如何reroute
!
问题:
是否可以在不重定向的情况下reroute
来自另一个操作的另一个控制器和操作,以及如何做到这一点?
或具体问题,当用户请求http://domain.com/API/{AnAction}
Version="2.0"
时,我reroute
APIController.Index
如何APIV2Controller.{AnAction}
?
我没有使用IoC。
答案 0 :(得分: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") }
);
这就是全部。这样就可以了。
答案 1 :(得分:0)
http://coderjournal.com/2010/09/simple-rest-api-versioning-using-mef-and-mvc/
这似乎完全符合您的要求,但通过使用完全不同的控制器集而不是重新路由它们需要采用一种非常不同的方法。
希望这有帮助。