想象一下你这样声明你的路线:
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帮助类,可以在here找到。
然后你只需要注册自定义选择器:
config.Services.Replace(typeof(IHttpControllerSelector), new VersionAwareControllerSelector(config));
有关完整示例 - have a look here on Github,它是 ASP.NET Web API 2 食谱书的一部分。