OData – API Versioning
前言
先看这 3 篇
ASP.NET Core – Web API Versioning
ASP.NET Core – Swagger OpenAPI (Swashbuckle)
ASP.NET Core – Swagger API Versioning
OData versioning 和普通 Web API versioning 大同小异,最大的区别是 EDM 是否换了。
主要参考
Docs – aspnet-api-versioning example(新的)
API versioning extension with ASP.NET Core OData 8(旧的)
Step by Step
安装 package
dotnet add package Microsoft.AspNetCore.OData
dotnet add package Asp.Versioning.Mvc
dotnet add package Asp.Versioning.OData
Product Model
namespace ODataVersioning; public class Product1 { public int Id { get; set; } public string Name { get; set; } = ""; } public class Product2 { public int Id { get; set; } public string Name { get; set; } = ""; public int Age { get; set; } }
有 2 个版本的 Product。
Product ModelConfiguration
public class ProductModelConfiguration : IModelConfiguration { private static void ConfigureV1(ODataModelBuilder builder) { builder.EntitySet<Product1>("products"); } private static void ConfigureV2(ODataModelBuilder builder) { builder.EntitySet<Product2>("products"); } public void Apply(ODataModelBuilder builder, ApiVersion apiVersion, string? routePrefix) { switch (apiVersion.MajorVersion) { case 1: ConfigureV1(builder); break; case 2: ConfigureV2(builder); break; default: ConfigureV2(builder); break; } } }
ModelConfiguration 是让我们声明不同版本使用不同 EDM model 的地方。IModelConfiguration 可以有很多个,通常为了方便管理,一个 Entity 会有一个 IModelConfiguration。
Program.cs
首先是基本的 OData 配置,我们不在这里设置 EMD 了哦。
builder.Services.AddControllers().AddOData( options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(null) );
setup API versioning
var apiVersioningBuilder = builder.Services.AddApiVersioning(options => { options.ReportApiVersions = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; }) .AddMvc().AddOData(options => options.AddRouteComponents("api/v{version:apiVersion}"));
主要是加了 .AddOData 这一句,它会去查找所有的 IModelConfiguration 做 setup。
.AddMvc 不是必须的,因为我的 Controller 是 Web API 混搭 OData(odata 负责 get 而已)所以才需要。
注:Swagger 暂时不要放哦。
Product Controller
[ODataAttributeRouting] [ApiController] [ApiVersion("1.0", Deprecated = true)] [ApiVersion("2.0")] [Route("api/v{version:apiVersion}")] public class ProductController : ControllerBase { [EnableQuery] [HttpGet("products"), MapToApiVersion("1.0")] public IEnumerable<Product1> GetProducts_v1() { return _products_v1; } [EnableQuery] [HttpGet("products"), MapToApiVersion("2.0")] public IEnumerable<Product2> GetProducts_v2() { return _products_v2; } [EnableQuery] [HttpGet("products/{id}"), MapToApiVersion("2.0")] public ActionResult<Product2> GetProduct(int id) { return Ok(SingleResult.Create(_products_v2.AsQueryable().Where(e => e.Id == id))); } [ODataIgnored] [HttpPost("products"), MapToApiVersion("2.0")] public ActionResult CreateProduct() { return CreatedAtAction(nameof(GetProduct), new { id = 3 }, new Product2 { Id = 3, Name = "p3", Age = 3 }); } public static readonly List<Product1> _products_v1 = [ new () { Id = 1, Name = "p1" }, new () { Id = 2, Name = "p2" } ]; public static readonly List<Product2> _products_v2 = [ new () { Id = 1, Name = "p1", Age = 1 }, new () { Id = 2, Name = "p2", Age = 2 } ]; }
和 API Versioning 没有太多的区别。唯一需要注意的是,Controller 一定要有 [ODataAttributeRouting],不然某些情况下 response 会变成普通的 Web API 而不是 OData。
具体细节和原因我懒得去查,我猜是 Bug,总之顺风水使用 [ODataAttributeRouting] + [ODataIgnored] 就对了。
测试
http://localhost:5298/api/v2.0/products http://localhost:5298/api/v2.0/products/1 POST http://localhost:5298/api/v2.0/products
Swagger
OData 的 swagger 和普通 Web API 的 Swagger 配置差不多。查看这篇 ASP.NET Core – Swagger API Versioning。
唯一的区别是需要安装
dotnet add package Asp.Versioning.OData.ApiExplorer
还有
就可以了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
2018-10-25 Angular 学习笔记 (Material Datepicker)