ASP.NET Core 入門教程 3、ASP.NET Core MVC路由入門

来源:https://www.cnblogs.com/ken-io/archive/2018/09/26/aspnet-core-tutorial-mvc-route.html
-Advertisement-
Play Games

一、前言 1、本文主要內容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC帶路徑參數的路由示例 ASP.NET Core MVC固定前/尾碼的路由示例 ASP.NET Core MVC正則表達式匹配路由示例 ASP.NET Core MVC路由約束與自定義路由約束 ...


一、前言

1、本文主要內容

  • ASP.NET Core MVC路由工作原理概述
  • ASP.NET Core MVC帶路徑參數的路由示例
  • ASP.NET Core MVC固定前/尾碼的路由示例
  • ASP.NET Core MVC正則表達式匹配路由示例
  • ASP.NET Core MVC路由約束與自定義路由約束
  • ASP.NET Core MVC RouteAttribute綁定式路由使用介紹

2、本教程環境信息

軟體/環境說明
操作系統 Windows 10
SDK 2.1.401
ASP.NET Core 2.1.3
IDE Visual Studio Code 1.27
瀏覽器 Chrome 69

本篇代碼基於上一篇進行調整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02

3、前置知識

你可能需要的前置知識

  • MVC框架/模式介紹

https://baike.baidu.com/item/mvc

  • 正則表達式

http://www.runoob.com/regexp/regexp-tutorial.html

二、ASP.NET Core MVC 路由簡介

1、ASP.NET Core MVC路由工作原理概述

ASP.NET Core MVC路由的作用就是將應用接收到請求轉發到對應的控制器去處理。

應用啟動的時候會將路由中間件(RouterMiddleware)加入到請求處理管道中,並將我們配置好的路由載入到路由集合(RouteCollection)中。當應用接收到請求時,會在路由管道(路由中間件)中執行路由匹配,並將請求交給對應的控制器去處理。

另外,需要特別註意的是,路由的匹配順序是按照我們定義的順序從上之下匹配的,遵循是的先配置先生效的原則。

2、路由配置參數說明

參數名說明
name 路由名稱,不可重覆
template 路由模板,可在模板中以{name}格式定義路由參數
defaults 配置路由參數預設值
constraints 路由約束

在路由配置中,MVC框架內置了兩個參數,controller,action。
路由匹配通過後,需要根據這兩個參數將當前請求交由對應的Controller+Action去處理。所以,這兩個參數缺少任何一個,都會導致路由無法正常工作。
通常我們有兩個選擇:

  • 在template中指定{controller},{action}參數
  • 在預設值中為controller、action指定預設值

三、ASP.NET Core MVC 路由示例

1、準備工作

為了方便我們進行測試,我們先準備好承接路由的Controller&Action

  • 創建TutorialController

在Controllers文件夾下新增控制器TutorialController.cs並繼承於Controller

using System;
using Microsoft.AspNetCore.Mvc;

namespace Ken.Tutorial.Web.Controllers
{
    public class TutorialController : Controller
    {

    }
}
  • 增加Action:Index
public IActionResult Index()
{
    return Content("ASP.NET Core Tutorial by ken from ken.io");
}
  • 增加Action:Welcome
public IActionResult Welcome(string name, int age)
{
    return Content($"Welcome {name}(age:{age}) !");
}

2、帶路徑參數的路由

路由配置:

routes.MapRoute(
        name: "TutorialPathValueRoute",
        template: "{controller}/{action}/{name}/{age}"
    );

此路由適配URL:

  • /tutorial/welcome/ken/20

不適配URL:

  • /tutorial/welcome/ken

如果我們希望不在路徑中設置age,也可以被路由到,那麼可以將age指定為可選參數,將模板中的{age}修改為{age?}即可

routes.MapRoute(
        name: "TutorialPathValueRoute",
        template: "{controller}/{action}/{name}/{age?}"
    );

此路由適配URL:

  • /tutorial/welcome/ken/20
  • /tutorial/welcome/ken
  • /tutorial/welcome/ken?age=20

3、固定前尾碼的路由

固定首碼路由配置:

routes.MapRoute(
    name: "TutorialPrefixRoute",
    template: "jiaocheng/{action}",
    defaults: new { controller = "Tutorial" }
);

此路由適配URL:

  • /jiaocheng/index
  • /jiaocheng/welcome

由於路徑參數中不包含controller參數,所以需要在預設值中指定。

固定尾碼路由配置

routes.MapRoute(
    name: "TutorialSuffixRoute",
    template: "{controller}/{action}.html"
);

此路由適配URL:

  • /tutorial/index.html
  • /tutorial/welcome.html
  • /home/index.html
  • /home/time.html

固定尾碼的路由適用於偽靜態等訴求
固定前尾碼可以根據自己的需求結合起來使用。
當然,你也可以在路由模板中間設定固定值。

四、ASP.NET Core MVC 路由約束

1、路由約束介紹

路由約束主要是用於約束路由參數,在URL格式滿足路有模板要求之後,進行參數檢查。如果參數不滿足路由約束,那麼依然會返回未匹配該路由。最常用的可能就是參數類型校驗、參數長度校驗、以及通過正則滿足的複雜校驗。

在開始之前需要在Startup.cs中引用相關命名空間

using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;

2、參數長度約束

路由配置:約束name長度不能>5

routes.MapRoute(
    name: "TutorialLengthRoute",
    template: "hello/{name}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" },
    constraints: new { name = new MaxLengthRouteConstraint(5) }
);

此路由適配

  • /hello
  • /hello/ken
  • /hello/ken/1000

次路由不適配

  • /hello/kenaaaa

我們也可以直接在模板中配置路由約束:

routes.MapRoute(
    name: "TutorialLengthRoute2",
    template: "hello2/{name:maxlength(5)}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" }
);

3、參數範圍約束

路由配置:約束 1<=age<=150

routes.MapRoute(
    name: "TutorialLengthRoute",
    template: "hello/{name}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" },
    constraints: new {  age = new CompositeRouteConstraint(new IRouteConstraint[] { 
                            new IntRouteConstraint(), 
                            new MinRouteConstraint(1), 
                            new MaxRouteConstraint(150) }) }
);

此路由適配:

  • /hello/ken/1
  • /hello/ken/150

此路由不適配

  • /hello/ken/1000

我們也可以直接在模板中配置路由約束:

routes.MapRoute(
    name: "TutorialLengthRoute2",
    template: "hello2/{name}/{age:range(1,150)?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" }
);

4、帶有正則表達式約束的路由

路由配置:

routes.MapRoute(
    name: "TutorialRegexRoute",
    template: "welcome/{name}",
    defaults: new { controller = "Tutorial", Action = "Welcome" },
    constraints: new { name = @"k[a-z]*" }
);

此路由適配:

  • /welcome/k
  • /welcome/ken
  • /welcome/kevin

此路由不適配

  • /welcome/k1
  • /welcome/keN
  • /welcome/tom

這裡我們用正則表達式約束了參數name,必須通過正則k[a-z]*匹配通過,即:以小寫字母k開頭,且後續可跟0到多個小寫字母

我們也可以直接在模板中配置路由約束:

routes.MapRoute(
    name: "TutorialRegexRoute2",
    template: "welcome2/{name:regex(@"k[a-z]*")}",
    defaults: new { controller = "Tutorial", Action = "Welcome" }
);

5、自定義路由約束

1、創建自定義約束

在項目根目錄創建目錄Common,併在目錄創建類:NameRouteConstraint.cs,然後實現介面:IRouteConstraint

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Ken.Tutorial.Web.Common
{
    public class NameRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            string name = values["name"]?.ToString();
            if (name == null) return true;
            if (name.Length > 5 && name.Contains(",")) return false;
            return true;
        }
    }
}

這裡我們約束當name長度>5時,name中不能包含,

2、路由配置

引入命名空間

using Ken.Tutorial.Web.Common;

在ConfigureServices引入路由約束

public void ConfigureServices(IServiceCollection services)
    {
        //引入MVC模塊
        services.AddMvc();

        //引入自定義路由約束
        services.Configure<RouteOptions>(options =>
        {
            options.ConstraintMap.Add("name", typeof(NameRouteConstraint));
        });
    }

配置路由

routes.MapRoute(
    name: "TutorialDiyConstraintRoute",
    template: "diy/{name}",
    defaults: new { controller = "Tutorial", action = "Welcome" },
    constraints: new { name = new NameRouteConstraint() }
);

此路由適配:

  • /diy/ken
  • /diy/ken,
  • /diy/kenny

此路由不適配

  • /diy/kenny,

當然,按照慣例,依然可以在模板中配置路由約束

routes.MapRoute(
    name: "TutorialDiyConstraintRoute2",
    template: "diy2/{name:name}",
    defaults: new { controller = "Tutorial", action = "Welcome" }
);

五、ASP.NET Core MVC 綁定式路由配置

1、路由配置風格

  • 集中式配置

前面章節提到的路由配置都是在Startup類中進行的集中式路由配置,集中配置的路由,除了template中沒有配置{controller}參數,預設都是對所有控制器(Controller)生效的。這種集中配置的方式一般我們只要配置一個預設路由,其他情況我們只需要不滿足預設模板的情況下進行配置即可。尤其是對URL沒有友好度要求的應用,例如:後臺管理系統

  • 分散式配置/綁定式配置

對於集中式路由配置的方式,如果某個Controller/Action配置了特殊路由,對於代碼閱讀就會不太友好。不過沒關係,ASP.NET Core MVC也提供了RouteAttribute可以讓我們在Controller或者Action上直接指定路由模板。

不過要強調的是,一個控制器只能選擇其中一種路由配置,如果控制器標記了RouteAttribute進行路由配置,那麼集中式配置的路由將不對其生效。

2、綁定式路由配置

在項目Controllers目中新建TestController.cs繼承與Controller
並配置Action與路由

using System;
using Microsoft.AspNetCore.Mvc;

namespace Ken.Tutorial.Web.Controllers
{
    [Route("/test")]
    public class TestController : Controller
    {
        [Route("")]
        [Route("/test/home")]
        public IActionResult Index()
        {
            return Content("ASP.NET Core RouteAttribute test by ken from ken.io");
        }

        [Route("servertime")]
        [Route("/t/t")]
        public IActionResult Time(){
            return Content($"ServerTime:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - ken.io");
        }
    }
}
配置項說明
[Route(“/test”)] 表示該Controller訪問路由首碼為/test,必須以/開頭
[Route(“”)] 表示以Controller的路由配置為首碼訪問該Action;可以通過/test路由到該Action
[Route(“/test/home”)] 表示忽略Controller的路由配置;可以通過/test/home路由到該Action
[Route(“servertime”)] 表示以Controller的路由配置為首碼訪問該Action;可以通過/test/servertime路由到該Action
[Route(“/t/t”)] 表示忽略Controller的路由配置;可以通過/t/t路由到該Action

RouteAttribute中配置的參數,就相當於我們集中式配置中的路由模板(template),最終框架還是幫我們初始化成路由規則,以[Route(“/test/home”)]為例,相當於生成了以下路由配置:

routes.MapRoute(
    name: "Default",
    template: "test/home",
    defaults: new { controller = "Test", action = "Index" }
);

當然,我們也可以在[Route]配置中使用模板參數,而且依然可以在模板中使用約束,自定義約束也沒問題。

[Route("welcome/{name:name}")]
public IActionResult Welcome(string name){
    return Content($"Welcome {name} !");
}

最大的區別就是不能定義預設值了,可能也不需要了,你說是吧。^_^

六、備註

1、附錄

  • 本文代碼示例

https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-03

  • 本文參考

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-2.1


本文首發於我的獨立博客:https://ken.io/note/asp.net-core-tutorial-mvc-route

 


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

-Advertisement-
Play Games
更多相關文章
  • 一、依賴倒置(Dependency Inversion Principle) 依賴倒置是面向對象設計領域的一種軟體設計原則。(其他的設計原則還有:單一職責原則、開放封閉原則、里式替換原則、介面分離原則,合稱SOLID) 話說設計原則有什麼用呢? 設計原則是無數編程前輩總結下來的經驗,好似編程界的金科 ...
  • 摘要:IIS配置成功後,系統一直提示無法載入應用程式集,iis已經進行過net frame重新註冊,bin文件夾也設置了everyone許可權,無論怎麼搗騰,都提示無法載入相應的程式,通過查閱網上N多資料,終於找到了相關設置方法,先記錄如下:錯誤信息: c_sharp_無法載入應用程式表現形式 處理方 ...
  • 1、右擊安裝編輯程式,在“視圖”菜單中,選擇“註冊表”。 2、創建“鍵”:HKCU\Software\Microsoft\Windows\CurrentVersion\Run 3、右鍵Run,新建“字元串值”。在屬性頁面設置name和value值([TARGETDIR]Form1.exe)。 ...
  • 一、添加引用 System.DirectoryServices System.DirectoryServices.AccountManagement 二、驗證代碼 聲明域 驗證代碼 三、開放埠 如果調用不通,需要防火牆開放389埠 ...
  • 一、基本介紹 回憶:最早接觸Expression是在學校接觸到EF的時候,發現where方法里的參數是Expression<Func<T,bool>>這麼一個類型,當初也只是看到了,也沒有過多的去探究,只是知道傳入lambda表達式使用即可,對於Expression和裡面的Func<T,bool>到 ...
  • 客戶端對文件的分割: ind.IsBusy = true; ind.Text = "上傳中...."; string cs_str = "server=" + GlobalVars.g_ServerID + "&userid="+GlobalVars.g_userID; string url = G ...
  • 預處理器指令指導編譯器在實際編譯開始之前對信息進行預處理。所有的預處理器指令都是以 # 開始。 #define 預處理器指令創建符號常量。#define 允許您定義一個符號,這樣,通過使用符號作為傳遞給 #if 指令的表達式,表達式將返回 true。在程式調試和運行上有重要的作用。比如預處理器指令可 ...
  • 由於項目需要,所以寫了下麵一段添加水印的代碼,如下: 後臺代碼: /// /// 上傳圖片 /// ///文件 ///保存的文件夾名稱 [HttpPost] public ActionResult UpLoadingImg(HttpPostedFileBase upfile, string file ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...