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模式

默認值

匹配URL模式的實例

{controller}/{action}/{id}

New {id=“”}

/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 都是正確的。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM