MVC路由機制

  按照傳統,在不少Web框架中(如經典的ASP、JSP、PHP、ASP.NET等之類的框架),URL表明的是磁盤上的物理文件。例如,當看到請求http://example.com/albums/list.aspx時,咱們能夠肯定該站點目錄結構中含有一個albums文件夾,而且在該文件夾下還有一個list.aspx文件。
  URL和文件系統之間這種一一對應的關係並不適用於大部分基於MVC的Web框架,如ASP.NET MVC.通常來講,這些框架採用不一樣的方法將URL映射到某個類上的方法調用,而不是映射到磁盤上的物理文件。
  另外,對於MVC應用程序,URL 請求到達的第一個組件是控制器而不是視圖,而控制器是沒有物理路徑的

路由機制概述 正則表達式

1.匹配傳入的請求(該請求不匹配服務器文件系統中文件),並將這些請求映射到控制器操做(Controller中的action方法)服務器

 

MVC基本的處理流程:來了一個URL請求, 從中找到Controller和Action的值, 將請求傳遞給Controller處理. Controller獲取Model數據對象, 而且將Model傳遞給View, 最後View負責呈現頁面。(說白了,就是來了一個URL,找到一個控制器中的方法)(路由是模式,有參數,經過URL中的參數,就能夠對應找到符合這種路由模式的方法)框架

Routing的做用:函數

´URL: localhost/home/index
´localhost是域名, 因此首先要去掉域名部分: home/index
´對應了上面代碼中的這種URL結構: {controller}/{action}/{id}
´由於咱們創建了這種URL結構的識別規則, 因此可以識別出 Controller是home, action是index, id沒有則爲默認值"".
路由機制通常是由路由名稱,路由模式和默認值構成的
Defaults屬性
最通常的路由狀況
routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "GlobalIndex", id = UrlParameter.Optional }
            );

路由URL模式post

默認值測試

匹配URL模式的實例url

{controller}/{action}/{id}spa

New {id=「」}code

/albums/display/123對象

/albums/display

{controller}/{action}/{id}

New {controller=「home」,

action=「index」,

id=「」}

/albums/display/123

/albums/display

/albums

/

若是一條URL可以匹配就會出錯
好比
Test的控制器裏有兩個action
public ActionResult Index()
public ActionResult Index(int id)

在頁面中有一個請求
Test/Index 或者Test/Index/3 都會出錯:
  對控制器類型「TestController」的操做「Index」的當前請求在下列操做方法之間不明確:
  類型 MVCDemo.Controllers.TestController 的 System.Web.Mvc.ActionResult Index()
  類型 MVCDemo.Controllers.TestController 的 System.Web.Mvc.ActionResult Index(Int32)
由於在這種最通常的狀況下,這條URL可以匹配兩條路由,用兩個方法都行。也就是說,來了一個URL,到控制器裏找到兩個方法均可以用。
      這就是控制器方法不能重載的緣由
 
註冊路由的順序
    當一個URL請求到達應用程序時,路由引擎將遍歷全部已註冊的路由,檢查請求URL是否和URL模式相匹配,而後根據指定的約束驗證檢索到的URL參數是否有效。一旦路由引擎找到第一個匹配的路由,就會中止遍歷。
´
   所以,路由的註冊順序很是重要,必須按照從最特殊到最通用的順序註冊。
routes.MapRoute("showBlogRoute",
               "blog/post/{id}",
                new { controller =「CMS」,action = 「Show」,id=「」});   
       
  routes.MapRoute("blogRoute", 
                「blog/{action}/{id}",
                new { controller = "CMS", action = 「Index", id = 「」});

routes.MapRoute(「DefaultRoute」, // 路由名稱 
                "{controller}/{action}/{id}", // 帶有參數的 URL
                new { controller = "Home", action = "Index", id =「」} // 參數默認值
            );
                
    當URL    /blog/post/3  到達應用程序時,路由引擎開始對路由列表進行評估,因爲URL和第一個參數路由相匹配,於是中止評估路由。若是按照相反的順序註冊路由,URL將匹配默認的路由,從而調用BlogController中的Post方法,顯然就得不到想要的結果
     當路由模式的控制器部分寫的是 {controller} 時,能夠匹配任何URL中的控制器部分,當是blog時,只能匹配 blog/... 的路由
 
Constraints屬性
 
 Constraints屬性是一個包含針對URL參數的驗證規則的字典,就是說,它是用來限定每一個參數的規則或Http請求的類型的
 使用正則表達式來定義約束,好比下面的例子,若是但願以正確的格式(只容許數字值)指定年月日
routes.MapRoute("simple",
                "archive/{year}/{month}/{day}",
                new{controller="blog",action="search",year="2009",month="10",day="10"},
                new{
                   year=@"\d{2}|\d{4}",//只能是兩位或四位數字
                   month=@"\d{1,2}",//只能使用一位或兩位數字
                   day=@"\d{1,2}"//只能使用一位或兩位數字
              });

 

2.構造傳出的URL,用來響應控制器中的操做

 

    在視圖中調用一個方法如Html.ActionLink或Url.Action的方法。 這方法會調用RouteCollection. GetVirtualPath方法,傳入參數用於選擇正確的路線生成的URL。

 

 

  <div>
        @Html.ActionLink("點擊","Click","Home");
    </div>

 

RouteCollection. GetVirtualPath方法

 

 

 返回值類型爲VirtualPathData,包含路由關聯的 URL 路徑的相關信息。

 

 定義了兩個重載函數

方法

 

說明

GetVirtualPath(RequestContext, RouteValueDictionary)

若是具備指定的上下文和參數值,則返回與路由關聯的 URL 路徑的相關信息。

GetVirtualPath(RequestContext, String, RouteValueDictionary)

若是具備指定的上下文、路由名稱和參數值,則返回與命名路由關聯的 URL 路徑的相關信息。

          第一個方法得到了當前路由的一些信息和用戶指定的路由值(字典)去選擇目標路由。 

          1.  路由系統而後會循環整個路由表,經過GetVirtualPath方法向每個路由發問:「Can you generate a URL given  these parameters?

           2.  若是答案是Yes,那麼就會返回一個VirtualPathData實例,包括URL和與匹配相關的一些其餘信息。若是答案是NO,則返回一個Null,路由系統會轉向下一條路由,直到遍歷整個路由表。

 

舉例:

若是咱們在路由機制中定義了一個

 routes.MapRoute(
                name: "test",
                url: "test/look/{id}",
                defaults: new { controller = "Home", action = "Click", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

在視圖中寫:

    <div>
        @Html.ActionLink("測試","look","test");
    </div>

   <div>
        @Html.ActionLink("點擊","Click","Home");
    </div>

最終的結果是 無論點擊哪個按鈕,都會觸發方法Click

public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Click()
        {
            return View();
        }

    }

可是顯示的URL都是

若是咱們在地址欄中直接輸入 test/look或者Home/Click 都是正確的。

相關文章
相關標籤/搜索