前言

在后端Api的开发过程中,无法避免的会遇到接口迭代的过程,如何保证新老接口的共存和接口的向前的兼容呢,这时候就需要对Api进行版本的控制,那如何优雅的控制Api的版本呢?

开始

Microsoft.AspNetCore.Mvc.Versioning 是一个微软官方推出的一个用于管理Api版本的包,配置简单,功能强大。 github地址.

新建一个WebApi项目并通过命令引用包。

Install-Package Microsoft.AspNetCore.Mvc.Versioning

最新版本已经支持Core3.1

项目结构如下

在 Startup 的 ConfigureServices 中增加一下配置。

services.AddApiVersioning(options =>
{options.ReportApiVersions = true; options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0);
});
  • ReportApiVersions:是否在请求头中返回受支持的版本信息。

  • AssumeDefaultVersionWhenUnspecified:请求没有指明版本的情况下是否使用默认的版本。

  • DefaultApiVersion:默认的版本号。

通过QueryString进行版本控制

分别在两个不同的Controller中添加一个获取版本信息的接口

namespace version.Controllers.v1
{[ApiVersion("1.0")][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}
namespace version.Controllers.v2
{[ApiVersion("2.0")][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}

HttpContext.GetRequestedApiVersion().ToString() 是用于获取请求接口的版本信息。

我们通过postman来请求这两个接口当我们没有给到具体请求哪个版本的时候会根据在ConfigureServices中配置的默认版本去执行。

指定版本请求结果

在响应头中会显示当前支持的所有的Api版本

通过URL Path进行版本控制

一般在Api开发中不会去QueryString的方式去进行版本控制,而是使用URL路径段的方式来控制版本。

修改两个Controller中的代码如下。

namespace version.Controllers.v1
{[ApiVersion("1.0")][ApiController][Route("api/v{version:ApiVersion}/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}
namespace version.Controllers.v2
{[ApiVersion("2.0")][ApiController][Route("api/v{version:ApiVersion}/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}

通过postman进行测试



可以看到当我们使用指定的版本是可以正常访问的时候,但是如果我们去掉了Api版本号就会抛出404,并不能像QueryString一样调用默认的Api版本,因为URL Path的方式不允许隐式匹配设置的默认Api版本。所以必须申明所有的Api版本。且在请求Api同时必须带上Api版本号。

通过Media Type进行版本控制

我们还可以使用content-type来实现版本的控制

修改ConfigureServices中的配置

services.AddApiVersioning(options =>
{options.ApiVersionReader = new MediaTypeApiVersionReader();options.AssumeDefaultVersionWhenUnspecified = true;options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);});

CurrentImplementationApiVersionSelector 如果没有在content-type中传递Api版本好,将默认匹配最新的Api版本

分别修改两个Controller

namespace version.Controllers.v1
{[ApiVersion("1.0")][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}
namespace version.Controllers.v2
{[ApiVersion("2.0")][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}

使用Postman测试

通过自定义Headers进行版本控制

修改ConfigureServices中的配置

services.AddControllers();
services.AddApiVersioning(options =>
{options.ReportApiVersions = true;options.ApiVersionReader = new HeaderApiVersionReader("api_version");options.AssumeDefaultVersionWhenUnspecified = true;options.DefaultApiVersion = new ApiVersion(1, 0);
});

api_version 是你Headers中Key的名字。

使用Postman测试

特性

当哪个Api版本不在更新,就需要弃用掉这个版本。当Deprecated值为true时说明该Api版本已经已经弃用,但是弃用不代表不能请求。只是会在响应头中告知次版本已经已经弃用。

namespace version.Controllers.v1
{[ApiVersion("1.0",Deprecated= true)][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}

项目总有一些功能是不需要版本的控制,所以我们希望它不受版本控制。可以添加[ApiVersionNeutral]特性使Api支持版本控制。

namespace version.Controllers.v1
{[ApiVersionNeutral][ApiController][Route("api/[controller]")]public class ValuesController : Controller{[HttpGet("version")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());}
}

MapToApiVersion 可以将单个Api归类于任何版本。在一个Controller中可以存在多个版本的Api。我们可以配合Deprecated来灵活的控制我们的Api。

namespace version.Controllers.v1
{[ApiVersion("3.0")][ApiVersion("1.0",Deprecated= true)][ApiController][Route("api/v{version:ApiVersion}/[controller]")]public class ValuesController : Controller{[HttpGet("version"), MapToApiVersion("1.0")]public string Version() => (HttpContext.GetRequestedApiVersion().ToString());[HttpGet("version3"), MapToApiVersion("3.0")]public string Version3() => (HttpContext.GetRequestedApiVersion().ToString());}
}

通过postman测试一下。

总结

可以看到Microsoft.AspNetCore.Mvc.Versioning功能还能强大的,基本满足了大部分的需求,还有一些功能可能没有在本文中涉及到,可以去这里.翻阅。

Asp.Net.Core WebApi 版本控制相关推荐

  1. ASP.Net Core WebApi几种版本控制对比

    ASP.Net Core WebApi几种版本控制对比 原文:ASP.Net Core WebApi几种版本控制对比 一.版本控制的好处: (1)有助于及时推出功能, 而不会破坏现有系统. (2)它还 ...

  2. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  3. IIS部署asp.net core webapi

    一.需要安装Windows Server Hosting,作用是让IIS有方向代理功能(Asp.Net Core Module负责反向代理工作),将请求转发到Kestrel,Windows serve ...

  4. NET问答: 如何将 ASP.NET Core WebAPI 中抛出的异常封装成对象?

    咨询区 rianjs: 在 ASP.NET Core WebAPI 中,我的 Controller 代码如下: [Route("create-license/{licenseKey}&quo ...

  5. 【源码解读】Vue与ASP.NET Core WebAPI的集成

    在前面博文[Vue]Vue 与 ASP.NET Core WebAPI 的集成中,介绍了集成原理:在中间件管道中注册SPA终端中间件,整个注册过程中,终端中间件会调用node,执行npm start命 ...

  6. 【Vue】Vue与ASP.NET Core WebAPI的集成

    SPA单页面应用已经遍地开花,熟知的三大框架,Angular.Vue和React,其中Angular与React均可集成至ASP.NET Core,且提供了相关了中间件.但是Vue没有: " ...

  7. ASP.NET CORE WEBAPI文件下载

    最近要使用ASP.NET CORE WEBAPI用来下载文件,使用的.NET CORE 3.1.考虑如下场景: 文件是程序生成的. 文件应该能兼容各种格式. 浏览器可以感知进行下载. 准备 经过简单的 ...

  8. Asp.Net Core WebAPI+PostgreSQL部署在Docker中

    PostgreSQL是一个功能强大的开源数据库系统.它支持了大多数的SQL:2008标准的数据类型,包括整型.数值值.布尔型.字节型.字符型.日期型.时间间隔型和时间型,它也支持存储二进制的大对像,包 ...

  9. asp.net core webApi 参数保护

    Intro asp.net core data protection 扩展,基于 IDataProtector 扩展的数据保护组件,自动化的实现某些参数的保护 ParamsProtection Par ...

最新文章

  1. Android中用Application类实现全局变量
  2. 关于python中requests模块导入问题-python中requests模块的使用方法
  3. spark sql 上个月_Spark学习之路 (十八)SparkSQL简单使用
  4. Hitv8 文件批量重命名工具
  5. elipse+pydev+python开发arcgis脚本程序
  6. PYPL 6 月编程语言排行
  7. CLR探索系列:托管PE/COFF文件格式侧窥
  8. html 强制占据一行,html – 如何强制内联div保持在同一行?
  9. vue json对象转数组_年薪百万之路--第六十七天 Vue入门
  10. CentOS7配置阿里源
  11. Android Studio 报错 Error:Some file crunching failed, see logs for details
  12. BP神经网络回归预测模型(python实现)
  13. (LeetCode)数数关系——Non-decreasing Array(非递减数组)
  14. python保存表情包_用Python一键保存半佛仙人所有的骚气表情包
  15. Vue3中setup前写async页面不显示
  16. Chapter 14
  17. [十月往昔]——Linux内核中的list.h浅谈
  18. 百度语音合成(TTS) 在Android的使用方法
  19. Matlab代码之plot函数的坐标点显示
  20. 总结的面试中常见65种应聘技巧回答

热门文章

  1. readonly和const的区别
  2. Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
  3. SetComputerName改网络中计算机名
  4. 转载 Android解决java.lang.OutOfMemoryError: bitmap size exceeds VM budget
  5. 您可能没有注意到的7个Ubuntu File Manager功能
  6. 对01背包的分析与理解(图文)
  7. 怎样用原生js配合css的transition写个无缝滚动
  8. sql 中 limit 与 limit,offset连用的区别
  9. Android渠道包自动化验证
  10. 图解ArcGIS API for JavaScript开发环境搭建