<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何實現(xiàn) ASP.NET Core WebApi 的版本化

          共 6416字,需瀏覽 13分鐘

           ·

          2021-01-06 20:56


          Web API 的版本化可以盡量保證在相同url情況下保留一個 api 的多個版本,通常一個 webapi 會有多個client,這些client包括:app,web,html5,crawl 等等同構或者異構的平臺,當 api 升級之后,往往升級前的 api 也得保留,當維護兩個api的時候就是一個不小的挑戰(zhàn),畢竟還是存在一些 client 用戶需要訪問老的api,這時候就需要將 webapi 版本化。

          安裝 Versioning 包

          要想使用 webapi 的版本化功能,需要用 nuget 引用?Microsoft.AspNetCore.Mvc.Versioning?包,還可以通過 Visual Studio 2019 的?NuGet package manager?可視化界面安裝 或者 通過?NuGet package manager?命令行工具輸入以下命令:


          dotnet?add?package?Microsoft.AspNetCore.Mvc.Versioning

          啟動 API 版本化

          當包成功添加到項目之后,接下來就可以在?Startup.ConfigureServices?中將 ApiVersioning 注入到容器中,如下代碼所示:


          ????public?class?Startup
          ????{
          ????????public?void?ConfigureServices(IServiceCollection?services)
          ????????{
          ????????????services.AddControllers();

          ????????????services.AddApiVersioning();
          ????????}
          ????}

          在調(diào)用?AddApiVersioning()?的時候記得?using Microsoft.AspNetCore.Mvc.Versioning,除了這個默認方法,還可以做一些全局配置,如下代碼所示:


          ????public?class?Startup
          ????{
          ????????public?void?ConfigureServices(IServiceCollection?services)
          ????????{
          ????????????services.AddControllers();

          ????????????services.AddApiVersioning(v?=>
          ????????????{
          ????????????????v.ReportApiVersions?=?true;
          ????????????????v.AssumeDefaultVersionWhenUnspecified?=?true;
          ????????????????v.DefaultApiVersion?=?new?ApiVersion(1,?0);
          ????????????});
          ????????}
          ????}

          使用 QueryString 指定版本號

          先來看一下代碼,考慮如下的 api。


          ????[ApiController]
          ????[ApiVersion("2.0")]
          ????[Route("api/[controller]")]
          ????public?class?WeatherForecastController?:?ControllerBase
          ????{
          ????????private?static?readonly?string[]?Summaries?=?new[]
          ????????{
          ????????????"Freezing",?"Bracing",?"Chilly",?"Cool",?"Mild",?"Warm",?"Balmy",?"Hot",?"Sweltering",?"Scorching"
          ????????};

          ????????[HttpGet]
          ????????public?IEnumerable?Get()
          ????????{
          ????????????var?rng?=?new?Random();
          ????????????return?Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast
          ????????????{
          ????????????????Date?=?DateTime.Now.AddDays(index),
          ????????????????TemperatureC?=?rng.Next(-20,?55),
          ????????????????Summary?=?Summaries[rng.Next(Summaries.Length)]
          ????????????})
          ????????????.ToArray();
          ????????}
          ????}

          從代碼中可以看到,我在 WeatherForecastController 上標記了該 Controller 是 v2.0 版本,接下來如何訪問呢?可以通過如下鏈接:?http://localhost:61582/api/weatherforecast?api-version=2.0

          看到這里,有些朋友就有疑問了,v2.0?的 Get 是有了,那?v1.0?的 Get 怎么訪問呢?實際開發(fā)中的做法是這樣的,會用兩個命名空間來表示相應的版本號,可以看如下代碼:


          namespace?WebApplication6.Controllers.v1
          {
          ????[ApiController]
          ????[ApiVersion("1.0")]
          ????[Route("api/[controller]")]
          ????public?class?WeatherForecastController?:?ControllerBase
          ????{
          ????????private?static?readonly?string[]?Summaries?=?new[]
          ????????{
          ????????????"Freezing",?"Bracing",?"Chilly",?"Cool",?"Mild",?"Warm",?"Balmy",?"Hot",?"Sweltering",?"Scorching"
          ????????};

          ????????private?readonly?ILogger?_logger;

          ????????public?WeatherForecastController(ILogger?logger)
          ????????{
          ????????????_logger?=?logger;
          ????????}

          ????????[HttpGet]
          ????????public?IEnumerable?Get()
          ????????{
          ????????????var?rng?=?new?Random();
          ????????????return?Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast
          ????????????{
          ????????????????Date?=?DateTime.Now.AddDays(index),
          ????????????????TemperatureC?=?rng.Next(-20,?55),
          ????????????????Summary?=?Summaries[rng.Next(Summaries.Length)]
          ????????????})
          ????????????.ToArray();
          ????????}
          ????}
          }


          namespace?WebApplication6.Controllers.v2
          {
          ????[ApiController]
          ????[ApiVersion("2.0")]
          ????[Route("api/[controller]")]
          ????public?class?WeatherForecastController?:?ControllerBase
          ????{
          ????????private?static?readonly?string[]?Summaries?=?new[]
          ????????{
          ????????????"Freezing",?"Bracing",?"Chilly",?"Cool",?"Mild",?"Warm",?"Balmy",?"Hot",?"Sweltering",?"Scorching"
          ????????};

          ????????private?readonly?ILogger?_logger;

          ????????public?WeatherForecastController(ILogger?logger)
          ????????{
          ????????????_logger?=?logger;
          ????????}

          ????????[HttpGet]
          ????????public?IEnumerable?Get()
          ????????{
          ????????????var?rng?=?new?Random();
          ????????????return?Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast
          ????????????{
          ????????????????Date?=?DateTime.Now.AddDays(index),
          ????????????????TemperatureC?=?rng.Next(-20,?55),
          ????????????????Summary?=?Summaries[rng.Next(Summaries.Length)]
          ????????????})
          ????????????.ToArray();
          ????????}
          ????}
          }

          從上面代碼可以看到?WebApplication6.Controllers.v1?表示版本 v1.0 ,?WebApplication6.Controllers.v2?表示版本 v2.0,接下來依次瀏覽這兩個url。

          使用 routes 指定版本號

          很顯然使用 QueryString 的方式不是很優(yōu)雅也不符合 Restful 規(guī)范,接下來看一下如何通過 Route 改造,考慮下面的類,請注意我是如何在 route 中進行版本化的。


          ????[ApiController]
          ????[ApiVersion("1.0")]
          ????[Route("api/v{version:apiVersion}/[controller]")]
          ????public?class?WeatherForecastController?:?ControllerBase
          ????{
          ????????private?static?readonly?string[]?Summaries?=?new[]
          ????????{
          ????????????"Freezing",?"Bracing",?"Chilly",?"Cool",?"Mild",?"Warm",?"Balmy",?"Hot",?"Sweltering",?"Scorching"
          ????????};

          ????????[HttpGet]
          ????????public?IEnumerable?Get()
          ????????{
          ????????????var?rng?=?new?Random();
          ????????????return?Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast
          ????????????{
          ????????????????Date?=?DateTime.Now.AddDays(index),
          ????????????????TemperatureC?=?rng.Next(-20,?55),
          ????????????????Summary?=?Summaries[rng.Next(Summaries.Length)]
          ????????????})
          ????????????.ToArray();
          ????????}
          ????}

          在這里,我將?[Route("api/[controller]")]?替換成了?[Route("api/v{version:apiVersion}/[controller]")],接下來將項目跑起來,如下圖所示:

          忽略 API 版本

          在 API 版本化時,有些 API 可能只有一個版本的需求,這時候可以使用?ApiVersionNeutral?特性來忽視版本化,如下代碼所示:


          ????[ApiVersionNeutral]
          ????[Route("api/[controller]")]
          ????[ApiController]
          ????public?class?WeatherForecastController?:?ControllerBase
          ????{
          ????????private?static?readonly?string[]?Summaries?=?new[]
          ????????{
          ????????????"Freezing",?"Bracing",?"Chilly",?"Cool",?"Mild",?"Warm",?"Balmy",?"Hot",?"Sweltering",?"Scorching"
          ????????};

          ????????[HttpGet]
          ????????public?IEnumerable?Get()
          ????????{
          ????????????var?rng?=?new?Random();
          ????????????return?Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast
          ????????????{
          ????????????????Date?=?DateTime.Now.AddDays(index),
          ????????????????TemperatureC?=?rng.Next(-20,?55),
          ????????????????Summary?=?Summaries[rng.Next(Summaries.Length)]
          ????????????})
          ????????????.ToArray();
          ????????}
          ????}

          譯文鏈接:https://www.infoworld.com/article/3433156/advanced-versioning-in-aspnet-core-web-api.html


          往期精彩回顧




          【推薦】.NET Core開發(fā)實戰(zhàn)視頻課程?★★★

          .NET Core實戰(zhàn)項目之CMS 第一章 入門篇-開篇及總體規(guī)劃

          【.NET Core微服務實戰(zhàn)-統(tǒng)一身份認證】開篇及目錄索引

          Redis基本使用及百億數(shù)據(jù)量中的使用技巧分享(附視頻地址及觀看指南)

          .NET Core中的一個接口多種實現(xiàn)的依賴注入與動態(tài)選擇看這篇就夠了

          10個小技巧助您寫出高性能的ASP.NET Core代碼

          用abp vNext快速開發(fā)Quartz.NET定時任務管理界面

          在ASP.NET Core中創(chuàng)建基于Quartz.NET托管服務輕松實現(xiàn)作業(yè)調(diào)度

          現(xiàn)身說法:實際業(yè)務出發(fā)分析百億數(shù)據(jù)量下的多表查詢優(yōu)化

          關于C#異步編程你應該了解的幾點建議

          C#異步編程看這篇就夠了


          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  可以免费看av | 国产亚洲欧美精品久久 | 婷婷久久五月天 | 人妻巨大乳HD无码 | 色呦哟无码精品一区二区三区 |