自动给 Asp.Net Core WebApi 增长 ApiVersionNeutral
Intro
新增长一个 Controller 的时候,常常忘记在 Controller 上增长 ApiVersion ,结果就致使前端使用指定的 ApiVersion 访问的时候就会失败,不支持的 Api 版本。html
错误信息以下:前端
{ "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-versioninggit
使用 ApiVersion 会在注册服务的地方注册 ApiVersion 相关的服务github
services.AddApiVersioning();
找到源码 会发现注册服务的时候把 mvc 默认的 ActionSelector
替换成了 ApiVersionActionSelector
,而后查看 ApiVersionActionSelector
的源码,找到了如下几处关键代码json
ApiVersion 服务注册api
ApiVersionNeturalmvc
ApiVersionNeutralAttributeui
ApiVersionActionSelectorthis
ControllerApiVentionBuilderurl
总结以下:
若是 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 会常常变,可使用这种方式。
有问题欢迎联系~~
原文出处:https://www.cnblogs.com/weihanli/p/automatic-add-ApiVersionNetural.html