asp.net core 系列 5 路由(上)

来源:https://www.cnblogs.com/MrHSR/archive/2019/01/09/10244215.html
-Advertisement-
Play Games

一. 概述 介紹asp.net core路由時,我初步想了下,分幾篇來說明。 路由的知識點很多,參考了官方文檔提取出一些重要的知識點來說。 在ASP.NET Core中是使用路由中間件來匹配傳入請求的 URL 並將它們映射到操作(action方法)。路由是在程式啟動時進行傳統路由或屬性路由定義。 路 ...


一. 概述

  介紹asp.net core路由時,我初步想了下,分幾篇來說明。  路由的知識點很多,參考了官方文檔提取出一些重要的知識點來說。    在ASP.NET Core中是使用路由中間件來匹配傳入請求的 URL 並將它們映射到操作(action方法)。路由是在程式啟動時進行傳統路由或屬性路由定義。 路由描述如何將 URL 路徑與操作相匹配。 它還用於在響應中生成送出的 URL(用於鏈接)。

  路由操作既支持傳統路由,也支持屬性路由。也可混合使用。通常傳統路由用於為瀏覽器處理 HTML 頁面的控制器。屬性路由用於處理 web API 的控制器。

 

  1.1設置路由中間件

    要使用傳統路由,必須在UseMVC中間件中配置實現IRouteBuilder介面,在asp.net core mvc 2.2 框架下,應用程式Startup的Configure 方法中,預設路由設置如下:

  app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

    在對 UseMvc調用中,MapRoute 用於創建單個路由,亦稱 default 路由。 大多數 MVC 應用使用帶有模板的路由。對於default路由簡便的方法可以使用:

  app.UseMvcWithDefaultRoute();

    UseMvc 和 UseMvcWithDefaultRoute 可向中間件管道添加 RouterMiddleware 的實例。 MVC 不直接與中間件交互,而是使用路由來處理請求。 MVC 通過 MvcRouteHandler 實例連接到路由。

    UseMvc 不直接定義任何路由,它向屬性路由的路由集合添加占位符{controller=Home}/{action=Index}/{id?} 。通過重載 UseMvc(Action<IRouteBuilder>) 則允許用戶添加自己的路由,並且還支持屬性路由。

 

  1.2 傳統路由

    傳統路由是:具有描述性的路由方案,這樣URL具有可讀性。傳統路由格式:{controller=Home}/{action=Index}/{id?}這樣的url路徑是設定了一個約定: 第一段映射到控制器名稱, 第二段映射到操作名稱,第二段映射到可選ID。

 

    (1) 使用預設路由:  

    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");

      使用此預設路由時: url路徑/Products/List 將映射到程式ProductsController(控制器).List(action)中。 url路徑/Blog/Article/17將映射到程式BlogController(控制器).Article(action)中。

 

    (2) 多個路由:

      通過添加對 MapRoute 的多次調用,可以在 UseMvc 內添加多個路由。 這樣做可以定義多個約定,或添加專用於特定操作的傳統路由,比如:

  app.UseMvc(routes =>
    {
     routes.MapRoute("blog", "blog/{*article}",
            defaults: new { controller = "Blog", action = "Article" });
     routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
   });

      這裡的blog路由是一個專用的傳統路由,這表示blog使用傳統路由系統,但專用於特定的操作,也就是對於BlogController控制器的Article操作,此專用路由將始終映射。對於多個路由的路由集合會進行排序,並按添加順序進行處理,因此,在此示例中,將先嘗試 blog 路由,再嘗試 default 路由。

 

    (3)  action操作的區分

       在處理url請求時,當通過路由匹配到一個控制器內兩項相同的action名稱時,mvc必須進行區分,以選擇最佳候選項,否則會引發異常(AmbiguousActionException)。

    public class ProductsController : Controller
     {
       public IActionResult Edit(int id) { ... }

       [HttpPost]
       public IActionResult Edit(int id, Product product) { ... }
     }

      此Products控制器定義了二項操作,這兩項操作均與 URL 路徑的 /Products/Edit/17 匹配相同。解決方案是將要提交的action加上 Http 謂詞為 POST。這樣post過來時,就會選擇Edit(int, Product)

 

  1.3 屬性路由

    通過在控制器(Controller)或操作(Action)上放置路由可實現屬性路由。 不能通過傳統路由訪問定義屬性路由的操作,反之亦然。 控制器上的任何路由屬性,都會使控制器中的所有操作使用屬性路由。

    屬性路由使用一組屬性將action直接映射到路由模板。在下麵的示例中,Configure 方法使用 app.UseMvc();,不傳遞任何路由。 HomeController 將匹配一組 URL,這組 URL 與預設路由 {controller=Home}/{action=Index}/{id?} 匹配的 URL 類似:

    當去掉default預設路由模板後,只使用app.UseMvc()時。運行程式時,頁面報404錯誤:找不到 localhost 的網頁。

    app.UseMvc();

    

    (1) 屬性路由基本使用   

    如果定義了屬性路由的操作,此時就是啟動屬性路由功能。Home控制器的屬性路由示例如下:

    public class HomeController : Controller
    {
       [Route("")]
       [Route("Home")]
       [Route("Home/Index")]
       public IActionResult Index()
       {
          return View();
       }
    }

    在index的action上加[Route("")]屬性路由。 瀏覽器可以使用下麵三種url來訪問,也是程式啟動時的預設載入頁面:

      http://localhost:30081/

      http://localhost:30081/Home/

      http://localhost:30081/Home/index

 

    (2) 屬性路由精確控制

      屬性路由需要更多輸入來指定路由;傳統的預設路由處理路由的方式則更簡潔。 但是,屬性路由允許(並需要)精確控制應用於每項操作的路由模板。下麵示例是精確控制每項操作的路由模板,比如url訪問/home/index時,即是調用MyIndex的action方法。

    public class MyDemoController : Controller
    {
       [Route("")]
       [Route("Home")]
       [Route("Home/Index")]
       public IActionResult MyIndex()
       {
          return View("Index");
       }
    }

    

  1.4 使用 Http[Verb] 屬性的屬性路由

    屬性路由還可以使用 Http[Verb] 屬性,比如 HttpPostAttribute 所有這些屬性都可採用路由模板。 此示例展示,同一路由模板匹配的兩項操作:

     [HttpGet("/products")]
    public IActionResult ListProducts()
    {
       // ...
    }

    [HttpPost("/products")]
    public IActionResult CreateProduct(...)
    {
       // ...
    }

    當 Http 謂詞為 GET 時將執行ProductsApi.ListProducts 操作, 當 Http 謂詞為 POST 時將執行 ProductsApi.CreateProduct。生成 REST API 時,很少會在操作方法上使用 [Route(...)]。 建議使用更特定的 Http*Verb*Attributes 來明確 API 所支持的操作。 REST API 的客戶端需要知道映射到特定邏輯操作的路徑和 Http 謂詞。

    例如下麵一個web api訪問路由,使用Http*Verb*Attributes 來明確定義如下:

    public class ProductsApiController : Controller
    {
       [HttpGet("/products/{id}", Name = "Products_List")]
       public IActionResult GetProduct(int id) { ... }
    }

    上面定義只有針對如訪問url如: /products/3(而非 /products)之類的 URL才會執行 ProductsApi.GetProduct(int) 操作。

 

   1.5 路由合併

    若要使屬性路由減少重覆,可將控制器Controller上的路由屬性與各個操作Action上的路由屬性合併。 控制器上定義的所有路由模板均作為操作上路由模板的首碼。 在控制器上放置路由屬性會使控制器中的所有操作都使用屬性路由。

    下麵是一個web api的路由合併,訪問Get的方法的訪問路徑為: http://localhost:30081/api/Products/1

  [Route("api/Products")]
    public class ProductsApiController : Controller
    {
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
    }

    下麵是一個控制器的路由合併。訪問index頁面的訪問路徑為: http://localhost:30081/home/index

   [Route("Home")]
  public class HomeController : Controller
  {
    [Route("")]      // Combines to define the route template "Home"
    [Route("Index")] // Combines to define the route template "Home/Index"
    [Route("/")]     // Doesn't combine, defines the route template ""
    public IActionResult Index()
    {
      //...
    }
  }

 

  1.6 指定屬性路由參數約束
        [HttpGet("Home/{id:int}",Name = "Pri")]
        public IActionResult Privacy(int id)
        {
            return View();
        }

    如果輸入非整數類型的參數,瀏覽器提示:找不到與以下網址對應的網頁:http://localhost:30081/home/dd

 

   1.7 自定義路由屬性

    該框架中提供的所有路由屬性([Route(...)]、[HttpGet(...)] 等)都可實現 IRouteTemplateProvider介面。 當應用啟動時,MVC 會查找控制器類和操作方法上的屬性,並使用可實現 IRouteTemplateProvider的屬性生成一組初始路由。

    下麵使用IRouteTemplateProvider 來定義自己的路由屬性。每個 IRouteTemplateProvider 都允許定義一個包含自定義路由模板、順序和名稱的路由:

   public class MyApiControllerAttribute : Attribute, IRouteTemplateProvider
    {
        //實現介面的三個屬性,這裡的[controller]是一個標記替換。
        public string Template => "api/[controller]/{action}/{id?}";

        public int? Order { get; set; }

        public string Name { get; set; }
    }    

    public class ProductsApiController : Controller
    {
        // GET api/values/5
        //  [HttpGet("{id}")]
        [MyApiController()]
        public string Get(int id)
        {
            return "value";
        }
    }

    通過訪問url: http://localhost:30081/api/ProductsApi/get/1 來調用get方法。

   

  參考文獻

  官方資料:asp.net core routing


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題意 "題目鏈接" Sol 發現abcdef是互不相關的 那麼meet in the middle一下。先算出abc的,再算def的 註意d = 0的時候不合法(害我wa了兩發。。) cpp include define LL long long using namespace std; const ...
  • 一: BeautifulSoup的安裝: 下載地址:https://www.crummy.com/software/BeautifulSoup/bs4/download/4.6/ 下載後,解壓縮,然後放到Python目錄中。 我是Windows安裝Python3.6,目錄:D:\Python\Pyt ...
  • 題意 "題目鏈接" Sol 把前一半放在左邊,後一半放在右邊 meet in the middle一波 統計答案的時候開始想的是hash,然而MLE了兩個點 實際上只要排序之後雙指針掃一遍就行了 cpp include using namespace std; const int MAXN = 7, ...
  • enums枚舉是值類型,數據直接存儲在棧中,而不是使用引用和真實數據的隔離方式來存儲。 (1)預設情況下,枚舉中的第一個變數被賦值為0,其他的變數的值按定義的順序來遞增(0,12,3...),因此以下兩個代碼定義是等價的: enum TrafficLight { Green, Yellow, Red ...
  • 表達式目錄樹 1.什麼是表達式目錄樹Expression? 表達式目錄樹是一個數據結構,語法樹。 首先我們去看看 Expressions類 ,定義了一個泛型委托類型 TDelegate: 我們先來一個帶返回值的委托: 其中m、n是兩個Int 類型的參數 通過表達式目錄樹計算 m*n+2: 通過中間語 ...
  • 工具是使用AES-256-CBC加密演算法 問題 最近有客戶反映, 在使用我們工具時候,會出現“調用的目標發生了異常”錯誤, 接到反饋之後, 我們進行了很多測試,甚至得到客戶系統信息和framework版本, 但是都沒有得到復現。測試,debug,log列印各種嘗試,無果。 **報錯信息顯示:** 原 ...
  • 所謂OJ,顧名思義Online Judge,一個用戶提交的程式在Online Judge系統下執行時將受到比較嚴格的限制,包括運行時間限制,記憶體使用限制和安全限制等。用戶程式執行的結果將被Online Judge系統捕捉並保存,然後再轉交給一個裁判程式。該裁判程式或者比較用戶程式的輸出數據和標準輸出 ...
  • 什麼是人工智慧 人工智慧是電腦科學的一個分支,它企圖瞭解智能的實質,並生產出一種新的能以人類智能相似的方式做出反應的智能機器,該領域的研究包括機器人、語言識別、圖像識別、自然語言處理和專家系統等。 我們來談談人工智慧 人工智慧自誕生以來,技術日益成熟,應用領域也在不斷擴大,從我們日常用的智能音箱, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...