前言
OData versioning 和普通 Web API versioning 最大区别就是 EDM 是否换了.
Web API 可能只是操作的细节换掉了, 我们就可以开一个新的 version. 但是 EDM 换就很大动作了. 就好比, 一个操作换了和一个数据结构换了的区别.
主要参考
API versioning extension with ASP.NET Core OData 8
没有换 EDM 的情况
就那我的例子来说, Web API 和 OData share 一个 Controller. 我的 Web API 要做 versioning, 但 OData 我的 EDM 没有不同的话. 大概长这样
[ApiController] [ApiVersion("1.0")] [ApiVersion("2.0")] [Route("api/v{version:apiVersion}")] public class MyController : ControllerBase { [ODataAttributeRouting] [HttpGet("products"), MapToApiVersion("1.0")] // api/v1.0/products [EnableQuery] public IEnumerable<Product> GetXyz_v1() { return _products; } [ODataAttributeRouting] [HttpGet("products"), MapToApiVersion("2.0")] // api/v2.0/products [EnableQuery] public IEnumerable<Product> GetXyz_v2() { return _products; } [ODataAttributeRouting] [HttpGet("products/{id}")] [HttpGet("products({id})")] [EnableQuery] public Product GetAbc(int id) { return _products.Single(p => p.Id == id); } [HttpPost("products"), MapToApiVersion("1.0")] public ActionResult<Product> CreateProduct_v1([FromBody] CreateProductDTO dto) { return Ok(); } [HttpPost("products"), MapToApiVersion("2.0")] public ActionResult<Product> CreateProduct_v2([FromBody] CreateProductDTO dto) { return Ok(); } private readonly Product[] _products = new[] { new Product { Id = 1, Name = "n1" }, new Product { Id = 2, Name = "n2" } }; }
program.cs
builder.Services.AddControllers().AddOData(options => { options.TimeZone = TimeZoneInfo.Utc; options.Select().Expand().Filter().OrderBy().SetMaxTop(null).Count(); var builder = new ODataConventionModelBuilder(); builder.EnableLowerCamelCase(); builder.EntitySet<Product>("Products"); options.AddRouteComponents("api/v{version:apiVersion}", builder.GetEdmModel()); }); builder.Services.AddApiVersioning(options => { options.ReportApiVersions = true; });
api/v{version:apiVersion} 这个必须和 route("api/v{version:apiVersion}") 一模一样就可以了.
如果要做不同的 EDM, 就是参考上面的文章, 扩展 OData, 或者一个 Controller 一个 version, 不要用 api/v{version:apiVersion}
类似这样
options.AddRouteComponents("api/v1", builder.GetEdmModel()); options.AddRouteComponents("api/v2", builder2.GetEdmModel());
然后 route("api/v1")
我没有测试行不行,以后有需求再来补上扩展 OData 的呗
MyODataRoutingApplicationModelProvider