前言

先看这 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

还有

就可以了。

OData – API Versioning的更多相关文章

  1. api.versioning 版本控制 自动识别最高版本

    Microsoft.AspNetCore.Mvc.Versioning //引入程序集 .net core 下面api的版本控制作用不需要多说,可以查阅https://www.cnblogs.com/ ...

  2. api.versioning 版本控制 自动识别最高版本和多Area但同名Contoller问题解决办法

    Microsoft.AspNetCore.Mvc.Versioning //引入程序集 .net core 下面api的版本控制作用不需要多说,可以查阅https://www.cnblogs.com/ ...

  3. web api 2 学习笔记 (OData Batch request)

    之前介绍过OData 中实现RPC的写法,今天在来一个批量操作. 参考 : https://damienbod.wordpress.com/2014/08/14/web-api-odata-v4-ba ...

  4. 用ASP.NET Core 2.1 建立规范的 REST API -- HATEOAS

    本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblogs.com/cgzl/p/9019314 ...

  5. Restful Api 最佳实践

    Web APIs has become an very important topic in the last year. We at M-Way Solutions are working ever ...

  6. 让OData和NHibernate结合进行动态查询

    OData是一个非常灵活的RESTful API,如果要做出强大的查询API,那么OData就强烈推荐了.http://www.odata.org/ OData的特点就是可以根据传入参数动态生成Ent ...

  7. 关于RESTFUL API 安全认证方式的一些总结

    常用认证方式 在之前的文章REST API 安全设计指南与使用 AngularJS & NodeJS 实现基于 token 的认证应用两篇文章中,[译]web权限验证方法说明中也详细介绍,一般 ...

  8. SharePoint 2013 REST 以及 OData 基础

    这篇文章会介绍: 简单的介绍REST,OData OData实现细节 OData在SharePoint 2013中的实现 为什么REST很重要 过去几年基于REST的webservice在IT企业越来 ...

  9. 【转】简单的 Laravel 5 REST API

    Introduction Almost all successful internet based companies have APIs. API is an acronym for Applica ...

  10. ASP.NET Core API 版本控制

    几天前,我和我的朋友们使用 ASP.NET Core 开发了一个API ,使用的是GET方式,将一些数据返回到客户端 APP.我们在前端进行了分页,意味着我们将所有数据发送给客户端,然后进行一些dat ...

随机推荐

  1. 深入理解 React 的 useSyncExternalStore Hook

    深入理解 React 的 useSyncExternalStore Hook 大家好,今天我们来聊聊 React 18 引入的一个新 Hook:useSyncExternalStore.这个 Hook ...

  2. Java JVM——12. 垃圾回收理论概述

    1.前言 1.1 什么是垃圾? 在提到什么是垃圾之前,我们先看下面一张图: 从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C++ 语言没有垃圾收集技 ...

  3. [oeasy]python0012_程序写错了怎么办

    运行python文件_报错处理_NameError 回忆上次内容 回忆 上次内容 vi oeasy.py 用 vi 编辑 oeasy.py   cat oeasy.py 用 cat 查看 oeasy. ...

  4. 使用threejs实现3D卡片菜单

    成品效果: 用到的技术:vue2.three.js.gsap.js template <template> <div id="box" class="c ...

  5. linux的一些常用端口

    hdfs:9870 yarn:8088 sparkMaster的端口是:8080 worker的端口是:8081 历史服务器的默认端口是: 18080

  6. hadoop 查看日志

    告警和日志信息监控 hadoop集群启动 su - hadoop #切换到hadoop用户 [hadoop@master ~]$ start-all.sh #启动 zookeeper集群启动 zkSe ...

  7. 【ActiveJdbc】05

    一.事务 通常在 Java ORM 中有一个显式连接或管理器对象(JPA 中的 EntityManager,Hibernate 中的 SessionManager 等). ActiveJDBC 中没有 ...

  8. 【JavaScript】无框架翻页处理

    这个业务太复杂了 输入框的东西要用接口查出来,居然不是用户手动输入 然后我就要做一个翻页的查询列表: <div form id="troublePartSearch" sty ...

  9. 【Shiro】05 自定义Realm认证实现

    [前提情要] Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息, 大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. 根接口:Realm ...

  10. 论文:使用分层强化学习进行空对空格斗(战斗机空对空搏斗)《Hierarchical Reinforcement Learning for Air-to-Air Combat》