自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral
自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral
Intro
新增加一个 Controller 的时候,经常忘记在 Controller 上增加 ApiVersion ,结果就导致前端使用指定的 ApiVersion 访问的时候就会失败,不支持的 Api 版本。
错误信息如下:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/values' does not support the API version '1.2'.",
"innerError": null
}
}
分析源代码
Asp.Net Core ApiVersion 源码地址:https://github.com/Microsoft/aspnet-api-versioning
使用 ApiVersion 会在注册服务的地方注册 ApiVersion 相关的服务
services.AddApiVersioning();
找到源码 会发现注册服务的时候把 mvc 默认的 ActionSelector 替换成了 ApiVersionActionSelector,然后查看 ApiVersionActionSelector 的源码,找到了以下几处关键代码
ApiVersion 服务注册

ApiVersionNetural

ApiVersionNeutralAttribute

ApiVersionActionSelector

ControllerApiVentionBuilder

总结如下:
如果 Controller 的 Attribute 定义的有 ApiVersionNeutralAttribute 就会忽略 ApiVersion 的限制,即使没有使用 ApiVersion 或者使用任意一个 ApiVersion 都可以路由到 Action,都可以访问得到,也不会出现开篇提到的错误。
解决方案
可以自己实现一个 IControllerModelConvention,去给没有定义 ApiVersion 的控制器加 ApiVersionNeutralAttribute,实现代码如下:
public class ApiControllerVersionConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
if (!(controller.ControllerType.IsDefined(typeof(ApiVersionAttribute)) || controller.ControllerType.IsDefined(typeof(ApiVersionNeutralAttribute))))
{
if (controller.Attributes is List<object>
attributes)
{
attributes.Add(new ApiVersionNeutralAttribute());
}
}
}
}
在注册 Mvc 服务的时候,配置 MvcOptions
services.AddMvc(options =>
{
options.Conventions.Add(new ApiControllerVersionConvention());
});
启动项目,这时候再访问原来因为没有定义 ApiVersion 的控制器下的路由,这时就不会再报错了,使用任意一个 ApiVersion 也都不会有问题了,问题解决啦~~~
扩展方法
为了方便使用,你也可以加一个扩展方法,在扩展方法里配置 MvcOptions,根据自己的需要,我觉得两种方式都 OK 的,扩展方法示例如下:
public static class MvcBuilderExtensions
{
public static IMvcBuilder AddApiControllerVersion(this IMvcBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.Configure<MvcOptions>(options=> options.Conventions.Add(new ApiControllerVersionConvention()));
return builder;
}
}
使用的时候可以直接在 AddMvc 之后加上扩展方法就可以了
services.AddMvc()
.AddApiControllerVersion();
End
问题解决,完美收官,最后还是要说一下,注意这个的使用情景,如果你要指定一个默认的 ApiVersion 有更好的方法,直接配置 ApiVersioningOptions 中的 DefaultApiVersion
就可以了
services.AddApiVersioning(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = ApiVersion.Default;
});
如果你的 ApiVersion 不定,可能有些 Api 的 ApiVersion 会经常变,可以使用这种方式。
有问题欢迎联系~~
自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral的更多相关文章
- ionic + asp.net core webapi + keycloak实现前后端用户认证和自动生成客户端代码
概述 本文使用ionic/angular开发网页前台,asp.net core webapi开发restful service,使用keycloak保护前台页面和后台服务,并且利用open api自动 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- ASP.NET Core WebApi使用Swagger生成api
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档
1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...
- Asp.Net Core WebAPI入门整理(四)参数获取
一.总结整理,本实例对应.Net Core 2.0版本 1.在.Net Core WebAPI 中对于参数的获取及自动赋值,沿用了Asp.Net MVC的有点,既可以单个指定多个参数,右可以指定Mo ...
- 【转】ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
原文链接:https://www.cnblogs.com/yilezhu/p/9241261.html 引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必 ...
- 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)
对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...
- ASP.NET Core WebAPI 开发-新建WebAPI项目
ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄 ...
- Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI
WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...
随机推荐
- 3种方法来在Linux电脑上查找文件
如果你不太了解Linux命令,那么在Linux系统里查找文件是比较困难的.只要使用多种不同的终端命令,可以很快地找到文件.Linux命令比其它操作系统的搜索功能更加强大,掌握这些命令就能你完全控制这些 ...
- [Swift]LeetCode256.粉刷房子 $ Paint House
There are a row of n houses, each house can be painted with one of the three colors: red, blue or gr ...
- [Swift]LeetCode354. 俄罗斯套娃信封问题 | Russian Doll Envelopes
You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...
- [Swift]LeetCode979. 在二叉树中分配硬币 | Distribute Coins in Binary Tree
Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there ar ...
- 巡风源码阅读与分析---view.py
巡风xunfeng----巡风源码阅读与分析 巡风是一款适用于企业内网的漏洞快速应急.巡航扫描系统,通过搜索功能可清晰的了解内部网络资产分布情况,并且可指定漏洞插件对搜索结果进行快速漏洞检测并输出结果 ...
- Python内置函数(20)——exec
英文文档: exec(object[, globals[, locals]]) This function supports dynamic execution of Python code. obj ...
- JVM基础系列开篇:为什么要学虚拟机?
跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看.所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试.但我经过了几年的学习和实战,我发现其实学习虚拟机并 ...
- 个人玩耍VUE..我的点点滴滴,今天很冷,2度!!!
谢谢博客园,可以记录我的点点滴滴.!!这个小案例的效果图 其中,这篇还是上一篇博客的序章,我们直接看下更新的代码. Cart.Vue <template> <div class=&q ...
- 并发编程(三)—— ReentrantLock的用法
ReentrantLock是Java并发包中提供的一个可重入的互斥锁.ReentrantLock和synchronized在基本用法,行为语义上都是类似的,同样都具有可重入性.只不过相比原生的Sync ...
- 【朝花夕拾】Android性能篇之(六)Android进程管理机制
前言 Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...