【问题标题】:ASP.NET MVC 3 Reroute to other controller and action & Restful API versioningASP.NET MVC 3 重新路由到其他控制器和操作 & Restful API 版本控制
【发布时间】:2011-08-21 09:03:19
【问题描述】:

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

(1) 起初我想为每个版本http://domain.com/API/{version} 使用TagBranch。因此,如果新的 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 参数中。因此 URL 固定为http://domain.com/API/,但用户必须指定Version 参数才能具有"1.0""2.0"

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

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

问题:

是否可以 reroute 另一个控制器和另一个动作中的动作而无需重定向以及如何做到这一点?

或者一个具体的问题,当用户请求http://domain.com/API/{AnAction}Version="2.0"时,我如何将rerouteAPIController.Index变成APIV2Controller.{AnAction}

我没有使用 IoC。

【问题讨论】:

  • 好像没有办法?

标签: asp.net-mvc asp.net-mvc-3 rest asp.net-web-api


【解决方案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") }
    );

就是这样。这样就可以了。

【讨论】:

    【解决方案2】:

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

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

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多