ASP.NET MVC 3 重新路由到其他控制器和操作& Restful API 版本控制

发布于 2024-11-06 07:59:11 字数 1714 浏览 0 评论 0原文

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

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

(2)然后我想用这种方式,一个版本一个控制器: (就像这个问题使用 ASP.NET MVC 3 构建的 REST API 的版本控制- 最佳实践)

http://domain.com/API/1.0/{AnAction} =>将转到 APIV1Controller.{AnAction}

http://domain.com/API/2.0/{AnAction} =>会转到 APIV2Controller.{AnAction}

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

(3) 第三种方式我从 PayPal API 得到了想法,即版本不在 URL 中,而是在 POST 参数中。因此,URL 固定为 http://domain.com/API/ 但用户必须指定 Version 参数以具有 "1.0" 或 <代码>“2.0”。

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

在 Google 和 Stackoverflow 上搜索如何在不重定向的情况下传输、调用或调用另一个控制器和操作之后。似乎没有好的答案和好的实践。有人回答不同控制器上的.NET MVC调用方法通过简单地创建控制器的新实例。突然我有了重新路由的想法!

问题:

是否可以在不重定向的情况下从另一个操作重新路由另一个控制器和操作以及如何做到这一点?

或者一个具体问题,当用户使用 Version="2.0" 请求 http://domain.com/API/{AnAction} 时,我如何重新路由< /code> 从 APIController.IndexAPIV2Controller.{AnAction}

我没有使用 IoC。

My original problem is I am looking what is the best practise to do versioning in Restful API. Not much people talk about this, dont have a good answer or I can't found exactly the solution at this moment.

(1) At first I am thinking to use Tag or Branch for each version http://domain.com/API/{version}. So if new API released, I Tag it, export and publish into the respective URL but seems hard to mix the different revision of source in one web application.

(2) Then I am thinking to use this way, one controller for one version:
(Just like this question 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}

but it need to write a route for each version.

(3) Third way I get the idea from PayPal API which is the version is not in the URL but in the POST parameter. So the URL fixed to http://domain.com/API/ but user must specify the Version parameter to have "1.0" or "2.0".

The solution for this: The (2) is ok for me, and currently I use this way but I want to mixed the (2) and (3) so I have a APIController which only have one Index action to check this Version parameter and transfer the request to the respective controller and action either APIV1Controller.{AnAction} or APIV2Controller.{AnAction}.

After Googling and Stackoverflowing about how to transfer, invoke or call another controller and action without redirection. Seems there is no good answer and good practise. Someone answer .NET MVC Call method on different controller by simply creating new instance of the controller. Suddenly I got the idea how about to reroute!

The question:

Is it possible to reroute the the other controller and action from another action without redirection and how to do that?

Or a specific question, when user request http://domain.com/API/{AnAction} with Version="2.0", how can I reroute from APIController.Index to APIV2Controller.{AnAction}?

I am not using IoC.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

高速公鹿 2024-11-13 07:59:11

这可以通过路由约束来完成。首先实现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") }
    );

仅此而已。这样就可以解决问题了。

This can be done via routing constraints. Firstly implement 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);
    }
}

Then register routes:

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") }
    );

That's all. This will do the trick.

与酒说心事 2024-11-13 07:59:11

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

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

希望这有帮助。

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

This seems to do exactly what you want, but it takes a very different approach by using a completely different set of controllers, rather than rerouting to them.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文