asp.net Web API中的路由-针对不同版本的API

本文关键字:API 版本 -针 路由 net asp Web | 更新日期: 2023-09-27 18:04:15

我从这里读到Attribute Routing in Web API 2

文章说,

Here are some other patterns that attribute routing makes easy.
API versioning
In this example, “/api/v1/products” would be routed to a different controller than “/api/v2/products”.
/api/v1/products
/api/v2/products

如何来吗?

编辑:我会在正常路由:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
         config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/v2/products",
            defaults: new { controller = V2_Products }
        );
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/v1/products",
            defaults: new { controller = V1_Products }
        );
    }
}

谁能告诉我如何在Attribute Routing方式做到这一点?为什么在这个例子中(根据文章)使用Attribute routing更容易和方便?

asp.net Web API中的路由-针对不同版本的API

使用属性路由实现版本控制的方法有很多;一个非常基本的方法是为每个版本的ApiController使用RoutePrefix属性

[RoutePrefix("v1")]
public class V1_ProductsController : ApiController
{
    [Route("products")]
    public IEnumerable<string> Get()
    {
        return new string[] { "v1-product1", "v1-product2" };
    }
     //....
}

[RoutePrefix("v2")]
public class V2_ProductsController : ApiController
{
     [Route("products")]
    public IEnumerable<string> Get()
    {
        return new string[] { "v2-product1", "v2-product2" };
    }
    //....
}

/v1/products转到第一个版本/v2/products转到第二个版本

您可以通过重写DefaultHttpControllerSelector

你可以重写方法来选择控制器

public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
            {
                HttpControllerDescriptor controllerDescriptor = null;
                IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping();
                IHttpRouteData routeData = request.GetRouteData();
                if (routeData == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
                object apiVersion;
                if (!routeData.Values.TryGetValue("Version", out apiVersion))
                {
                    apiVersion = "1";
                }

                object controllerName;
                if (!routeData.Values.TryGetValue("controller", out controllerName))
                {
                    controllerName = string.Empty;
                }
                if (controllerName == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
                string newControllerName = String.Concat(controllerName.ToString(), "V", apiVersion);
                if (controllers.TryGetValue(newControllerName, out controllerDescriptor))
                {
                    return controllerDescriptor;
                }
                if (controllers.TryGetValue(controllerName.ToString(), out controllerDescriptor))
                {
                    return controllerDescriptor;
                }
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
webapiconfig
 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{version}/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

并在webapiconfig

中注册控制器选择器
config.Services.Replace(typeof(IHttpControllerSelector), new ApiVersioningSelector(config));

所以从现在开始,如果你命名控制器ProductsV1Controller,它将引用/api/v1/products。另外请注意,我的例子也支持没有版本的路由,所以如果没有找到v1,它将尝试检查是否存在ProductsController

p。代码更新有一个bug:(

另一种简单的方法是将你的路由配置为api/{folder}/{controller}/{action},其中在文件夹中你可以指定名称为V1或V2。

一个好的方法是实现你自己的控制器选择器。您可以使用此链接获取更多信息。

Web API选择控制器的接口是IHttpControllerSelector。这个接口的重要方法是SelectController,它为给定的HttpRequestMessage选择一个控制器。