自動給 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