博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral
阅读量:5807 次
发布时间:2019-06-18

本文共 2558 字,大约阅读时间需要 8 分钟。

自动给 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 源码地址:

使用 ApiVersion 会在注册服务的地方注册 ApiVersion 相关的服务

services.AddApiVersioning();

会发现注册服务的时候把 mvc 默认的 ActionSelector 替换成了 ApiVersionActionSelector,然后查看 ApiVersionActionSelector 的源码,找到了以下几处关键代码

ApiVersion 服务注册

IServiceCollectionExtensions

ApiVersionNetural

apiversionneutral

ApiVersionNeutralAttribute

ApiVersionNeutralAttribute

ApiVersionActionSelector

ApiVersionActionSelector

ControllerApiVentionBuilder

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                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
(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 会经常变,可以使用这种方式。

有问题欢迎联系~~

转载地址:http://kcubx.baihongyu.com/

你可能感兴趣的文章
比特币系统采用的公钥密码学方案和ECDSA签名算法介绍——第二部分:代码实现(C语言)...
查看>>
分享15款很实用的 Sass 和 Compass 工具
查看>>
AMD优势: 与众不同 选择丰富
查看>>
玩转高性能超猛防火墙nf-HiPAC
查看>>
简单按日期查询mysql某张表中的记录数
查看>>
自动化部署之jenkins发布PHP项目
查看>>
C/C++编程可用的Linux自带工具
查看>>
如何判断webview是不是滑到底部
查看>>
海贼王十大悲催人物
查看>>
org.hibernate.MappingException: No Dialect mapping for JDBC type: -1 搞定!
查看>>
热点热词新闻资讯API开放接口(永久免费开放)
查看>>
8.1_Linux习题和作业
查看>>
11.排序算法_6_归并排序
查看>>
Redis redis-cli 命令列表
查看>>
.NET框架设计—常被忽视的框架设计技巧
查看>>
BigDecimal 舍入模式(Rounding mode)介绍
查看>>
开源 免费 java CMS - FreeCMS1.2-标签 infoSign
查看>>
开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据
查看>>
git reset 三种用法总结
查看>>
hdfs笔记
查看>>