我想在现有的 MVC 项目中构建版本化的 WebApi,以便我的 URL
/api/v1/account
/api/v2/account
我目前不使用区域,但经过一些研究,我认为这对我有用,但显然你不能嵌套
Areas
(我目前使用MVC4,但可以升级到5)。
我怎样才能最好地实现这一目标?
更新
我最终使用了这个
有两种方法可以使用 Web API 实现版本控制
方法一:
/api/accountv1/
/api/accountv2/
我发现对 API 进行版本控制的最简单方法是创建一个与“AccountV1Controller”相同的控制器并将其命名为“AccountV2Controller”,注意控制器名称中的后缀 V1 和 V2,我们将根据这部分来选择根据 API 版本选择适当的控制器。
方法2:
/api/v1/account
/api/v2/account
或者你可以使用 Routes 来获得相同的行为
config.Routes.MapHttpRoute(
name: "1-0Api",
routeTemplate: "api/v1/Account/{id}",
defaults: new { controller = "AccountV1", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "2-0Api",
routeTemplate: "api/v2/Account/{id}",
defaults: new { controller = "AccountV2", id = RouteParameter.Optional }
);
摘自这里
这里有两种方法,不需要您有 2 个单独的控制器类。
请求标头
推荐的版本控制设计之一是使用请求标头而不是 URL 参数。
if (Request.Headers["API Version"] == "2")
{
return Version2Code();
}
return Version1Code();
使用 RouteContraint
您也可以使用路线约束:
config.Routes.MapHttpRoute(
name: "versionedApi",
routeTemplate: "api/{version}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new {version = @"^[vV]\d+$"}
);
那么version就会像id一样成为路由函数参数。
public class AccountController: Controller {
public class ActionResult Index(object id, string version)
{
if (string.Equals(version, "v2", StringComparison.OrdinalIgnoreCase))
{
return Version2Code();
}
return Version1Code();
}
}
另外,请查看 Web API 2 属性路由
此外,如果您确实升级到 Mvc 5 和 WebAPI 2,还有如何使用属性路由来执行此操作的示例 http://www.asp.net/web-api/overview/web-api-routing-and-操作/属性路由in-web-api-2
如果您需要在 ASP.NET Web API 中进行 API 版本控制,Asp.Versioning.WebApi(以前称为 Microsoft.AspNet.WebApi.Versioning)是最直接、最强大的选项。
最简单的例子是:
[ApiVersion( 1.0 )]
[Route( "api/example" )]
public class ExampleController : ApiController
{
// GET api/example?api-version=1.0
public IHttpActionResult Get( ApiVersion apiVersion ) => ();
}
您可以按照自己喜欢的方式对 API 进行版本控制,包括通过 URL 段:
[ApiVersion( 1.0 )]
[RoutePrefix( "api/v{version:apiVersion}/example" )]
public class ExampleController : ApiController
{
// GET api/v{version}/helloworld
[Route]
public IHttpActionResult Get() => Ok();
}
您的设置将类似于:
public void Configuration( HttpConfiguration configuration )
{
// only required when versioning by url: ~/v{apiVersion}/{controller}
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) },
};
// reporting api versions will return the headers
// "api-supported-versions" and "api-deprecated-versions"
configuration.AddApiVersioning( options => options.ReportApiVersions = true );
configuration.MapHttpAttributeRoutes( constraintResolver );
}
现在大多数应用程序都使用直接路由(又名属性路由),但如果您想使用约定路由,那么支持就很好。
但是,由于 ASP.NET Web API 路由系统的限制,不建议混合使用路由方法。