對於Asp.Net Web Forms應用程式來說,要求的Url都是對應一個特定的實體檔案(http://xxx.com/default.aspx)。這樣的Url與具體實體檔案緊密綁定在一起,帶來了諸多方便的限制:可讀性、SEO優化等。為了解決這些局限性,微軟引進了URL路由系統。下面透過一個Demo來剖析一下Asp.Net的路由系統。
建立一個空的WebForm應用程序,在Global.asax.cs檔案中加入如下程式碼:
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { //处理匹配的文件 RouteTable.Routes.RouteExistingFiles = true; //url默认值 RouteValueDictionary defaults = new RouteValueDictionary() { { "name", "wuwenmao" }, { "id", "001" } }; //路由约束 RouteValueDictionary constraints = new RouteValueDictionary() { { "name", @"\w{2,10}" }, { "id", @"\d{3}" } }; //与路由相关的值,但不参与路由是否匹配URL模式 RouteValueDictionary dataTokens = new RouteValueDictionary() { { "defaultName", "wuwenmao" }, { "defaultId", "001" } }; RouteTable.Routes.MapPageRoute("default", "employees/{name}/{id}", "~/Default.aspx", false, defaults, constraints, dataTokens); } }
新建名為Default的WebForm頁面,頁面代碼如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <h1 id="这是Default-aspx页面">这是Default.aspx页面</h1> <p> RouteData中Values: <ul> <% foreach (var value in RouteData.Values) { %> <li> <%=value.Key %>=<%=value.Value %> </li> <%} %> </ul> RouteData中DataTokens: <ul> <% foreach (var value in RouteData.DataTokens) { %> <li> <%=value.Key %>=<%=value.Value %> </li> <%} %> </ul> </p> </form> </body> </html>
輸入路徑為一下三種,得到的結果都是一樣的:
http:/ /localhost:2947/employees/wuwenmao/001
http://localhost:2947/employees/wuwenmao
http://localhost:2947/employees/
原因是因為註冊路由的時候,為路由模板中的變數設定了預設值,所以當用以上三種url時是等效的。
回頭看Global檔案中,在註冊路由時也設定了一個變數:
這是使用正規規則限定了路由範本中變數的值,請求url中對應的變數值只有與正規符合才能正確請求,否則回傳404錯誤。如id值長度大於3時:
上面透過一個簡單的例子體驗了一下Asp.Net路由系統,下面我們透過翻看源碼來剖析一下Asp.Net路由系統的實作原理。
首先,我們Global檔案中使用下列語句註冊一個路由時,實際上是在全域路由表新增一個路由。
透過Reflector工具,我們可以看到:
現在有個問題,在註冊好路由之後, Asp.Net是如何使用路由系統的呢?實際上,Asp.Net路由系統是透過註冊一個HttpModule對象,由這個HttpModule對象實現針對請求進行攔截,然後動態映射到用於處理當前請求的HttpHandler對像中,最後通過HttpHandler對象對請求進行處理並響應。這個HttpModule其實就是UrlRoutingModule,我們在啟動Asp.Net程式時,透過Global檔案中的Modules屬性可以驗證,從下面截圖可以看到,Modules屬性中包含了已經註冊的HttpModule,其中就包含UrlRoutingModule:
在這個UrlRoutingModule裡面,又進行了哪些跟路由相關的操作呢,我們還是繼續翻看源碼:
透過上面的原始碼查看,我們可以看出,當有請求來到時,Asp.Net透過註冊的UrlRoutingModule模組攔截了請求,然後從全域路由表中尋找符合的RouteData,如果找得到,根據HttpApplication取得對應的HttpHandler,然後將其對應到目前請求上下文中,供後續的管道事件用來處理目前請求。
下面我們繼續翻閱原始碼,剖析一下UrlRoutingModule是怎麼從全域路由表中取得RouteData的:
從上面可以看到,UrlRoutingModule中調用全域路由表的GetRouteData,實際上是依序呼叫註冊的每個Route的GetRouteData,傳回第一個符合的RouteData,如果註冊的路由都不匹配,回傳null。
下面我們再來看看Route裡面的GetRouteData做了些什麼:
Match方法:
透過依序呼叫Route的GetRouteData方法,在GetRouteData方法中做了以下操作:
1、呼叫了ParsedRoute類型的Match方法進行請求Url和註冊在目前Route物件中的路由模板的匹配工作,如果沒有匹配,直接返回null;
2、如果請求Url和當前Route物件的路由模板匹配了,常見RouteData物件;
3.根據註冊路由資訊時定義的限制條件來檢驗目前請求Url是否通過,不透過返回null;
4、為RouteData物件的Values和DataTokens賦值操作;
5、返回RouteData物件;
到此,Asp.Net的路由系統基本上剖析完畢,還有很多細節限於篇幅沒辦法一一剖析。
總結:
透過以上的剖析,我們整理一下思路,對Asp.Net路由系統所做的工作做個總結:首先,我們在Global中註冊了Route對象,然後透過在Asp.Net註冊的HttpModule模組UrlRoutingModule進行攔截請求Url,之後從全域路由表RouteTables.Routes中依序呼叫Route物件的GetRouteData進行請求Url和註冊路由資訊的匹配,返回第一個匹配的RouteData,查找完整個RouteTables.Routes後面都沒有符合到,回傳null,最後會回傳404給前端頁面。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。
更多剖析Asp.Net路由系統實現原理相關文章請關注PHP中文網!

C#.NET生態系統提供了豐富的框架和庫,幫助開發者高效構建應用。 1.ASP.NETCore用於構建高性能Web應用,2.EntityFrameworkCore用於數據庫操作。通過理解這些工具的使用和最佳實踐,開發者可以提高應用的質量和性能。

如何將C#.NET應用部署到Azure或AWS?答案是使用AzureAppService和AWSElasticBeanstalk。 1.在Azure上,使用AzureAppService和AzurePipelines自動化部署。 2.在AWS上,使用AmazonElasticBeanstalk和AWSLambda實現部署和無服務器計算。

C#和.NET的結合為開發者提供了強大的編程環境。 1)C#支持多態性和異步編程,2).NET提供跨平台能力和並發處理機制,這使得它們在桌面、Web和移動應用開發中廣泛應用。

.NETFramework是一個軟件框架,C#是一種編程語言。 1..NETFramework提供庫和服務,支持桌面、Web和移動應用開發。 2.C#設計用於.NETFramework,支持現代編程功能。 3..NETFramework通過CLR管理代碼執行,C#代碼編譯成IL後由CLR運行。 4.使用.NETFramework可快速開發應用,C#提供如LINQ的高級功能。 5.常見錯誤包括類型轉換和異步編程死鎖,調試需用VisualStudio工具。

C#是一種由微軟開發的現代、面向對象的編程語言,.NET是微軟提供的開發框架。 C#結合了C 的性能和Java的簡潔性,適用於構建各種應用程序。 .NET框架支持多種語言,提供垃圾回收機制,簡化內存管理。

C#和.NET運行時緊密合作,賦予開發者高效、強大且跨平台的開發能力。 1)C#是一種類型安全且面向對象的編程語言,旨在與.NET框架無縫集成。 2).NET運行時管理C#代碼的執行,提供垃圾回收、類型安全等服務,確保高效和跨平台運行。

要開始C#.NET開發,你需要:1.了解C#的基礎知識和.NET框架的核心概念;2.掌握變量、數據類型、控制結構、函數和類的基本概念;3.學習C#的高級特性,如LINQ和異步編程;4.熟悉常見錯誤的調試技巧和性能優化方法。通過這些步驟,你可以逐步深入C#.NET的世界,並編寫高效的應用程序。

C#和.NET的關係是密不可分的,但它們不是一回事。 C#是一門編程語言,而.NET是一個開發平台。 C#用於編寫代碼,編譯成.NET的中間語言(IL),由.NET運行時(CLR)執行。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),