最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

ASP.NET Core MVC 配置全局路由前綴

來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 22:36:30
文檔

ASP.NET Core MVC 配置全局路由前綴

ASP.NET Core MVC 配置全局路由前綴:ASP.NET Core MVC 配置全局路由前綴 前言 大家好,今天給大家介紹一個 ASP.NET Core MVC 的一個新特性,給全局路由添加統(tǒng)一前綴。嚴格說其實不算是新特性,不過是Core MVC特有的。 應用背景 不知道大家在做 Web Api 應用程序的時候,有沒有遇到過這
推薦度:
導讀ASP.NET Core MVC 配置全局路由前綴:ASP.NET Core MVC 配置全局路由前綴 前言 大家好,今天給大家介紹一個 ASP.NET Core MVC 的一個新特性,給全局路由添加統(tǒng)一前綴。嚴格說其實不算是新特性,不過是Core MVC特有的。 應用背景 不知道大家在做 Web Api 應用程序的時候,有沒有遇到過這

ASP.NET Core MVC 配置全局路由前綴

前言

大家好,今天給大家介紹一個 ASP.NET Core MVC 的一個新特性,給全局路由添加統(tǒng)一前綴。嚴格說其實不算是新特性,不過是Core MVC特有的。

應用背景

不知道大家在做 Web Api 應用程序的時候,有沒有遇到過這種場景,就是所有的接口都是以 /api 開頭的,也就是我們的api 接口請求地址是像這樣的:

http://www.example.com/api/order/333

或者是這樣的需求

http://www.example.com/api/v2/order/333

在以前,我們如果要實現(xiàn)這種需求,可以在 Controller 中添加一個 [Route("/api/order")] 這樣的特性路由 Attribute,然后MVC 框架就會掃描你的路由表從而可以匹配到 /api/order 這樣的請求。

但是第二個帶版本號的需求,原本 Controller 的 Route 定義是 [Route("/api/v1/order")],現(xiàn)在要升級到v2,又有上百個接口,這就需要一個一個修改,可能就會懵逼了。

現(xiàn)在,有一種更加簡便優(yōu)雅的方式來做這個事情了,你可以統(tǒng)一的來添加一個全局的前綴路由標記,下面就一起來看看吧。

IApplicationModelConvention 接口

首先,我們需要使用到 IApplicationModelConvention這個接口,位于 Microsoft.AspNetCore.Mvc.ApplicationModels 命名空間下,我們來看一下接口的定義。

public interface IApplicationModelConvention
{
 void Apply(ApplicationModel application);
}
 

我們知道,MVC 框架有一些約定俗成的東西,那么這個接口就是主要是用來自定義一些 MVC 約定的一些東西的,我們可以通過指定 ApplicationModel 對象來添加或者修改一些約定。可以看到接口提供了一個 Apply的方法,這個方法有一個ApplicationModel對象,我們可以利用這個對象來修改我們需要的東西,MVC 框架本身在啟動的時候會注入這個接口到 Services 中,所以我們只需要實現(xiàn)這個接口,然后稍加配置即可。

那再讓我們看一下ApplicationModel 這個對象都有哪些東西:

public class ApplicationModel : IPropertyModel, IFilterModel, IApiExplorerModel
{
 public ApiExplorerModel ApiExplorer { get; set; }
 public IList<ControllerModel> Controllers { get; }
 public IList<IFilterMetadata> Filters { get; }

 public IDictionary<object, object> Properties { get; }
}

可以看到有 ApiExplorer,Controllers,Filters,Properties 等屬性。

  1. ApiExplorerModel:主要是配置默認MVC Api Explorer的一些東西,包括Api的描述信息,組信息,可見性等。
  2. ControllerModel:主要是 Comtroller 默認約定相關的了,這個里面東西就比較多了,就不一一介紹了,我們等下就要配置里面的一個東西。
  3. IFilterMetadata :空接口,主要起到標記的作用。

還有一個地方需要告訴大家的是,可以看到上面的 Controllers 屬性它是一個IList<ControllerModel>,也就是說這個列表中記錄了你程序中的所有 Controller 的信息,你可以通過遍歷的方式針對某一部分或某個 Controller 進行設置,包括Controller中的Actions的信息都可以通過此種方式來設置,我們可以利用這個特性來非常靈活的對 MVC 框架進行改造,是不是很炫酷。

下面,我們就利用這個特性來實現(xiàn)我們今天的主題。謝謝你點的贊~ :)

添加全局路由統(tǒng)一前綴

沒有那么多廢話了,直接上代碼,要說的話全在代碼里:

//定義個類RouteConvention,來實現(xiàn) IApplicationModelConvention 接口
public class RouteConvention : IApplicationModelConvention
{
 private readonly AttributeRouteModel _centralPrefix;

 public RouteConvention(IRouteTemplateProvider routeTemplateProvider)
 {
 _centralPrefix = new AttributeRouteModel(routeTemplateProvider);
 }

 //接口的Apply方法
 public void Apply(ApplicationModel application)
 {
 //遍歷所有的 Controller
 foreach (var controller in application.Controllers)
 {
 // 已經(jīng)標記了 RouteAttribute 的 Controller
 var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
 if (matchedSelectors.Any())
 {
 foreach (var selectorModel in matchedSelectors)
 {
 // 在 當前路由上 再 添加一個 路由前綴
 selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_centralPrefix,
 selectorModel.AttributeRouteModel);
 }
 }

 // 沒有標記 RouteAttribute 的 Controller
 var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
 if (unmatchedSelectors.Any())
 {
 foreach (var selectorModel in unmatchedSelectors)
 {
 // 添加一個 路由前綴
 selectorModel.AttributeRouteModel = _centralPrefix;
 }
 }
 }
 }
}

然后,我們就可以開始使用我們自己定義的這個類了。

public static class MvcOptionsExtensions
{
 public static void UseCentralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
 {
 // 添加我們自定義 實現(xiàn)IApplicationModelConvention的RouteConvention
 opts.Conventions.Insert(0, new RouteConvention(routeAttribute));
 }
}

最后,在 Startup.cs 文件中,添加上面的擴展方法就可以了。

public class Startup
{
 public Startup(IHostingEnvironment env)
 {
 //...
 }

 public void ConfigureServices(IServiceCollection services)
 {
 //...
 
 services.AddMvc(opt =>
 {
 // 路由參數(shù)在此處仍然是有效的,比如添加一個版本號
 opt.UseCentralRoutePrefix(new RouteAttribute("api/v{version}"));
 });
 }

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
 //...
 
 app.UseMvc();
 }
}

其中,opt.UseCentralRoutePrefix 就是上面定義的那個擴展方法,此處路由參數(shù)仍然是可以使用的,所以比如你可以給你的接口指定一個版本號之類的東西。這樣之后,你的所有 Controller 的 RoteAttribute 都會添加上了這個前綴,這樣就完美解決了最開始的那個版本號的需求。他們看起來大概是這樣的:

[Route("order")]
public class OrderController : Controller
{
 // 路由地址 : /api/v{version}/order/details/{id}
 [Route("details/{id}")]
 public string GetById(int id, int version)
 {
 //上面是可以接收到版本號的,返回 version 和 id
 return $"other resource: {id}, version: {version}";
 }
}

public class ItemController : Controller
{
 // 路由地址: /api/v{version}/item/{id}
 [Route("item/{id}")]
 public string GetById(int id, int version)
 {
 //上面是可以接收到版本號的,返回 version 和 id
 return $"item: {id}, version: {version}";
 }
}

總結

上面的黑體字,希望大家能夠理解并運用,這個例子只是實際需求中的很小的一個場景,在具體的項目中會有各種各樣正常或者非正常的需求,我們在做一個功能的時候要多多思考,其實 MVC 框架還有很多東西可以去學習,包括它的設計思想,擴展性等東西,都是需要慢慢領悟的。如果大家對 ASP.NET Core 感興趣,可以關注我一下,我會定期在博客中分享我的一些學習成果吧。

通過此文希望能幫助大家,謝謝大家對本站的支持!

聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

ASP.NET Core MVC 配置全局路由前綴

ASP.NET Core MVC 配置全局路由前綴:ASP.NET Core MVC 配置全局路由前綴 前言 大家好,今天給大家介紹一個 ASP.NET Core MVC 的一個新特性,給全局路由添加統(tǒng)一前綴。嚴格說其實不算是新特性,不過是Core MVC特有的。 應用背景 不知道大家在做 Web Api 應用程序的時候,有沒有遇到過這
推薦度:
標簽: 全局 配置 路由
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top