ASP.NET MVC 路由
一、理解默認路由表
當你創建一個新的ASP.NET MVC應用程序時,應用程序已經被配置爲使用ASP.NET路由。ASP.NET路由在兩個地方設置。
-
在你的應用程序Web配置文件(Web.config文件)中啓用ASP.NET路由。在配置文件中有四個節點與路由有關:sytem.web.httpModules節,system.web.httpHandlers節,system.webserver.modules節,以及system.webserver.handlers節。特別要小心不要刪除了這些節點,因爲沒有它們路由將不能工作。
-
也是更爲重要的一點,在應用程序的Global.asax文件中創建了一個路由表。Global.asax文件是一個特殊的文件,它包含了作用於ASP.NET應用程序生命週期事件的事件處理程序。路由表在Application Start事件期間創建。
例1:默認Global.asax文件
代碼清單1中的文件包含了一個ASP.NET MVC應用程序的默認Global.asax文件。
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
}
}
當一個MVC應用程序首次運行時,會調用Application_Start()方法。這個方法隨後調用了RegisterRoutes()方法。RegisterRoutes()方法創建了路由表。
默認的路由表包含了一個路由(名叫Default)。Default路由將URL的第一部分映射到控制器名,URL的第二部分映射到控制器動作,第三個部分映射到一個叫做id的參數。
假設你在瀏覽器的地址欄輸入了下面的URL:
/Home/Index/3
默認的路由將這個URL映射爲下面的參數:
Controller = Home
Action = Index
id = 3
當你請求URL /Home/Index/3時,將會執行下面的代碼:
HomeController.Index(3)
Default路由包含了所有三個參數的默認值。如果你不提供控制器,那麼控制器參數默認值爲Home。如果你不提供動作,動作參數默認爲值Index。最後,如果你不提供id,id參數默認爲空字符串。
讓我們看看幾個例子,Default路由是如何將URL映射到控制器動作的。設想你在瀏覽器地址欄輸入了下面的URL:
/Home
由於Default路由參數的默認值,輸入這個URL將會調用代碼清單2中的HomeController類的Index()方法。
例2:HomeController.cs
代碼清單2 - HomeController.cs
在代碼清單2中,HomeController類包含了一個叫做Index()的方法,它接受一個叫做Id的參數。URL /Home將會導致調用Index()方法,並使用空字符串作爲Id參數的值。
出於MVC框架調用控制器動作的方式,URL /Home也匹配代碼清單3中HomeController類的Index()方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
例3:HomeController.cs(不含參數的Index動作)
代碼清單3 - HomeController.cs(不含參數的Index動作)
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
代碼清單3中的Index()方法不接受任何的參數。URL /Home將會導致調用這個Index()方法。URL /Home/Index/3也會調用這個方法(Id被忽略)。
URL /Home也會匹配代碼清單4中HomeController類的Index()方法。
例4:HomeController.cs(使用可空參數的Index動作)
代碼清單4 - HomeController.cs(使用可空參數的Index動作)
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
return View();
}
}
}
在代碼清單4中,Index()方法擁有一個整數參數。因爲這個參數是一個可空參數(可以擁有Null值),因此可以調用Index()而不會引發錯誤。
最後,使用URL /Home 調用代碼清單5中的Index()方法將會引發一個異常,因爲Id參數並非一個可空參數。如果你試圖調用Index()方法,那麼你將會獲得一個圖1中所示的錯誤。
例5:HomeController.cs(含有Id參數的Index動作)
代碼清單5 - HomeController.cs(含有Id參數的Index動作)
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(int id)
{
return View();
}
}
}
二: URL舉例
就以下面這個URL爲例,介紹下普通URL的各部分組成
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
從上面的URL可以看出,一個完整的URL包括以下幾部分:
- 協議部分:該URL的協議部分爲“http:”,這代表網頁使用的是HTTP協議。在Internet中可以使用多種協議,如HTTP,FTP等等本例中使用的是HTTP協議。在"HTTP"後面的“//”爲分隔符
域名部分:該URL的域名部分爲“www.aspxfans.com”。一個URL中,也可以使用IP地址作爲域名使用 - 端口部分:跟在域名後面的是端口,域名和端口之間使用“:”作爲分隔符。端口不是一個URL必須的部分,如果省略端口部分,將採用默認端口
- 虛擬目錄部分:從域名後的第一個“/”開始到最後一個“/”爲止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”
- 文件名部分:從域名後的最後一個“/”開始到“?”爲止,是文件名部分,如果沒有“?”,則是從域名後的最後一個“/”開始到“#”爲止,是文件部分,如果沒有“?”和“#”,那麼從域名後的最後一個“/”開始到結束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名
- 錨部分:從“#”開始到最後,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分
- 參數部分:從“?”開始到“#”爲止之間的部分爲參數部分,又稱搜索部分、查詢部分。本例中的參數部分爲“boardID=5&ID=24618&page=1”。參數可以允許有多個參數,參數與參數之間用“&”作爲分隔符。
三: URL通用格式
URL的語法:大多數URL語法都建立在9個部分構成的通用格式上,而其中最重要的是方案(scheme)、主機(host)和路徑(path)
-
通用格式:方案://用戶名:密碼@主機名:端口/服務器上資源的路徑;參數?查詢#片段
-
方案:指訪問服務器以獲取資源時要使用哪種協議。比如,http、https和FTP等
-
主機和端口:指資源宿主服務器的主機名或IP地址。端口是指資源宿主服務器正在監聽的端口,很多HTTP的默認端口號是80。比如,130.32.12.34:800,這裏的IP地址是主機名,端口是800
-
用戶名和密碼:很多服務器都要求輸入用戶名和密碼纔會允許用戶訪問數據,如FTP服務器。
-
例子:joe是用戶名、joepasswd是密碼
ftp://joe:joepasswd@ftp.prep.edu/pub/name
路徑:路徑說明了資源位於服務器的什麼地方。
- 例子:/cans/index.html就是URL中的路徑
http://www.hda.com/cans/index.html
參數:爲了嚮應用程序提供它們所需要的輸入參數,以便正確地與服務器進行交互,URL中有個參數組件。由字符“;”將其與URL的其餘部分分隔開來。
- 例子:;type=7;nam=true就是兩個參數。
ftp://prep.mit.edu/pub;type=7;nam=true
查詢:很多資源,比如數據庫服務、搜索引擎,都可以通過提問題或進行查詢來縮小請求資源的範圍。由字符“?”將其與URL的其餘部分分隔開來。
- 例子:查詢組件有兩個名/值對:name=csh和age=24
http://www.cheng.cn/si.html?name=csh&age=24
片段:#代表網頁中的一個位置,其右面的字符就是該位置的標識符(一般情況下,錨鏈接會用到)
- 例子:下面的URL中,代表網頁si.index的print位置,瀏覽器讀取這個URL後,會自動將print位置滾動至可視區域。
http://www.cheng.cn/si.html#print
URL的分類:URL可以分爲絕對URL和相對URL
絕對URL:絕對URL中包含了訪問資源所需的全部信息。
案例:
相對URL:相對URL包含的只是訪問資源所需的部分信息。而要想得到訪問資源的全部信息的話,就要和另一個被稱爲基礎(base)的URL結合進行解析
案例:
相對URL中的基礎URL:轉換相對URL的第一步就是找到基礎URL
1、在資源中顯式地指定基礎URL。比如,HTML文檔中可能會包含一個定義了基礎URL的HTML標籤
2、封裝資源的基礎URL。在HTML中,基礎URL可以從它們所屬資源的基礎URL中推導出來
四:URL特殊字符
有些符號在URL中是不能直接傳遞的,如果要在URL中傳遞這些特殊符號,那麼就要使用他們的編碼了。編碼的格式爲:%加字符的ASCII碼,即一個百分號%,後面跟對應字符的ASCII(16進制)碼值。例如 空格的編碼值是"%20"。
下表中列出了一些URL特殊符號及編碼:
替換爲%3A
序號 | 符號 | 含義 | 十六進制 |
---|---|---|---|
1 | + | URL 中+號表示空格 | %2B |
2 | 空格 | URL中的空格可以用+號或者編碼 | %20 |
3 | / | 分隔目錄和子目錄 | %2F |
4 | ? | 分隔實際的 URL 和參數 | %3F |
5 | % | 指定特殊字符 | %25 |
6 | # | 表示書籤 | %23 |
7 | & | URL中指定的參數間的分隔符 | %26 |
8 | = | URL中指定參數的值 | %3D |
例:要傳遞字符串“this%is#te=st&o k?+/”作爲參數t傳給te.asp,則URL可以是:
te.asp?t=this%25is%23te%3Dst%26o%20k%3F%2B%2F 或者
te.asp?t=this%25is%23te%3Dst%26o+k%3F%2B%2F (空格可以用%20或+代替)