Asp.net web api ASP.NETMVC:拦截路由并转发到不同的操作/路由
我们的站点有一个RESTAPI。我们已经通过使用端点添加或更新的发布版本作为端点的前缀来对端点进行版本控制。比如说Asp.net web api ASP.NETMVC:拦截路由并转发到不同的操作/路由,asp.net-web-api,asp.net-mvc-routing,Asp.net Web Api,Asp.net Mvc Routing,我们的站点有一个RESTAPI。我们已经通过使用端点添加或更新的发布版本作为端点的前缀来对端点进行版本控制。比如说 /v1/service-a /v2/服务-b /v3/service-c 这种方法的问题是我们的客户端代码调用不同版本的端点。例如,页面可能会调用/v3/service-c和/v1/service-a 我想对其进行设置,这样我们的开发人员就可以通过在端点前面加上最新版本的端点来访问最新版本的API。使用上面的示例,页面将调用/v3/service-c和/v3/service-a
- /v1/service-a
- /v2/服务-b
- /v3/service-c
有什么想法吗?想象一下你这样宣布你的路线:
config.Routes.MapHttpRoute("defaultVersioned", "v{version}/{controller}/{id}",
new { id = RouteParameter.Optional }, new { version = @"\d+" });
config.Routes.MapHttpRoute("default", "{controller}/{id}",
new { id = RouteParameter.Optional });
现在,您可以使用特定的命名约定为不同的版本创建不同的控制器,例如:
public class FooController : ApiController {}
public class FooV2Controller : ApiController {}
public class FooV3Controller : ApiController {}
现在,因为版本是路由的一部分,所以您可以实现一个自定义控制器选择器,从路由中选择版本,并基于此选择相关的控制器
public class VersionAwareControllerSelector : DefaultHttpControllerSelector
{
public VersionAwareControllerSelector(HttpConfiguration configuration) : base(configuration) { }
public override string GetControllerName(HttpRequestMessage request)
{
var controllerName = base.GetControllerName(request);
var versionFinder = new VersionFinder();
var version = versionFinder.GetVersionFromRequest(request);
if (version > 0)
{
return GetVersionedControllerName(request, controllerName, version);
}
return controllerName;
}
private string GetVersionedControllerName(HttpRequestMessage request, string baseControllerName, int version)
{
var versionControllerName = string.Format("{0}v{1}", baseControllerName, version);
HttpControllerDescriptor descriptor;
if (GetControllerMapping().TryGetValue(versionControllerName, out descriptor))
{
return versionControllerName;
}
throw new HttpResponseException(request.CreateErrorResponse(
HttpStatusCode.NotFound,
String.Format("No HTTP resource was found that matches the URI {0} and version number {1}",
request.RequestUri, version)));
}
}
此代码使用可以找到的VersionFinder
helper类
然后您只需注册自定义选择器:
config.Services.Replace(typeof(IHttpControllerSelector), new VersionAwareControllerSelector(config));
作为一个完整的示例,它是ASP.NET Web API 2菜谱手册的一部分。想象一下,您这样声明您的路线:
config.Routes.MapHttpRoute("defaultVersioned", "v{version}/{controller}/{id}",
new { id = RouteParameter.Optional }, new { version = @"\d+" });
config.Routes.MapHttpRoute("default", "{controller}/{id}",
new { id = RouteParameter.Optional });
现在,您可以使用特定的命名约定为不同的版本创建不同的控制器,例如:
public class FooController : ApiController {}
public class FooV2Controller : ApiController {}
public class FooV3Controller : ApiController {}
现在,因为版本是路由的一部分,所以您可以实现一个自定义控制器选择器,从路由中选择版本,并基于此选择相关的控制器
public class VersionAwareControllerSelector : DefaultHttpControllerSelector
{
public VersionAwareControllerSelector(HttpConfiguration configuration) : base(configuration) { }
public override string GetControllerName(HttpRequestMessage request)
{
var controllerName = base.GetControllerName(request);
var versionFinder = new VersionFinder();
var version = versionFinder.GetVersionFromRequest(request);
if (version > 0)
{
return GetVersionedControllerName(request, controllerName, version);
}
return controllerName;
}
private string GetVersionedControllerName(HttpRequestMessage request, string baseControllerName, int version)
{
var versionControllerName = string.Format("{0}v{1}", baseControllerName, version);
HttpControllerDescriptor descriptor;
if (GetControllerMapping().TryGetValue(versionControllerName, out descriptor))
{
return versionControllerName;
}
throw new HttpResponseException(request.CreateErrorResponse(
HttpStatusCode.NotFound,
String.Format("No HTTP resource was found that matches the URI {0} and version number {1}",
request.RequestUri, version)));
}
}
此代码使用可以找到的VersionFinder
helper类
然后您只需注册自定义选择器:
config.Services.Replace(typeof(IHttpControllerSelector), new VersionAwareControllerSelector(config));
作为一个完整的示例,它是ASP.NET Web API 2菜谱手册的一部分