MVC涉及RouteTable自定義路徑


Routing

到目前為止,我們已經解決了MVC的很多問題,但忽略了最基本的最重要的一個問題:當用戶發送請求時,會發生什么?

最好的答案是“執行Action 方法”,但仍存在疑問:對於一個特定的URL請求,如何確定控制器和action 方法。在開始實驗31之前,我們首先來解答上述問題,你可能會困惑為什么這個問題會放在最后來講,因為了解內部結構之前,需要更好的了解MVC。

理解RouteTable

在Asp.net mvc中有RouteTable這個概念,是用來存儲URL 路徑的,簡而言之,是保存已定義的應用程序的可能的URL pattern的集合。

默認情況下,路徑是項目模板組成的一部分。可在 Global.asax 文件中檢查到,在 Application_Start中會發現以下語句:

   1:  RouteConfig.RegisterRoutes(RouteTable.Routes);

App_Start文件夾下的 RouteConfig.cs文件,包含以下代碼塊:

   1:  namespace WebApplication1
   2:  {
   3:      public class RouteConfig
   4:      {
   5:          public static void RegisterRoutes(RouteCollection routes)
   6:          {
   7:              routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   8:   
   9:              routes.MapRoute(
  10:                  name: "Default",
  11:                  url: "{controller}/{action}/{id}",
  12:                  defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  13:              );
  14:          }
  15:      }
  16:  }
 
 

RegisterRoutes方法已經包含了由routes.MapRoute 方法定義的默認的路徑。已定義的路徑會在請求周期中確定執行的是正確的控制器和action 方法。如果使用 route.MapRoute創建了多個路徑,那么內部路徑的定義就意味着創建Route對象。

MapRoute 方法也可與 RouteHandler 關聯。

理解ASP.NET MVC 請求周期

在本節中我們只講解請求周期中重要的知識點

1.  UrlRoutingModule

當最終用戶發送請求時,會通過UrlRoutingModule 對象傳遞,UrlRoutingModule 是HTTP 模塊。

2. Routing

UrlRoutingModule 會從route table集合中獲取首次匹配的Route 對象,為了能夠匹配成功,請求URL會與route中定義的URL pattern 匹配。

當匹配的時候必須考慮以下規則:

  • 數字參數的匹配(請求URL和URL pattern中的數字)

  • URL pattern中的可選參數:

  • 參數中定義的靜態參數


3. 創建MVC Route Handler

一旦Route 對象被選中,UrlRoutingModule會獲得 Route對象的 MvcRouteHandler對象。

4. 創建 RouteData 和 RequestContext

UrlRoutingModule使用Route對象創建RouteData,可用於創建RequestContext。RouteData封裝了路徑的信息如Controller名稱,action名稱以及route參數值。

Controller 名稱

為了從URL 中獲取Controller名稱,需要按規則執行如在URL pattern中{Controller}是標識Controller名稱的關鍵字。

Action Method 名稱

為了獲取action 方法名稱,{action}是標識action 方法的關鍵字。

Route 參數

URL pattern能夠獲得以下值:

1.{controller}

2.{action}

3. 字符串,如 “MyCompany/{controller}/{action}”,“MyCompany”是字符串。

4. 其他,如“{controller}/{action}/{id}”,”id“是路徑的參數。

例如:

Route pattern - > “{controller}/{action}/{id}”

請求 URL ->http://localhost:8870/BulkUpload/Upload/5

測試1

   1:  public class BulkUploadController : Controller
   2:  {
   3:      public ActionResult Upload (string id)
   4:      {
   5:         //value of id will be 5 -> string 5
   6:         ...
   7:      }
   8:  }

測試2

   1:  public class BulkUploadController : Controller
   2:  {
   3:      public ActionResult Upload (int id)
   4:      {
   5:         //value of id will be 5 -> int 5
   6:         ...
   7:      }
   8:  }

測試3

   1:  public class BulkUploadController : Controller
   2:  {
   3:      public ActionResult Upload (string MyId)
   4:      {
   5:         //value of MyId will be null
   6:         ...
   7:      }
   8:  }

 

5. 創建MVC Handler

MvcRouteHandler 會創建 MVCHandler的實例傳遞 RequestContext對象

6. 創建Controller實例

MVCHandler會根據 ControllerFactory的幫助創建Controller實例

7. 執行方法

MVCHandler調用Controller的執行方法,執行方法是由Controller的基類定義的。

8. 調用Action 方法

每個控制器都有與之關聯的 ControllerActionInvoker對象。在執行方法中ControllerActionInvoker對象調用正確的action 方法。

9. 運行結果

Action方法會接收到用戶輸入,並准備好響應數據,然后通過返回語句返回執行結果,返回類型可能是ViewResult或其他。

實驗31——實現對用戶有好的URL

1. 重新定義 RegisterRoutes  方法

RegisterRoutes 方法中包含 additional route

   1:  public static void RegisterRoutes(RouteCollection routes)
   2:  {
   3:      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   4:   
   5:      routes.MapRoute(
   6:      name: "Upload",
   7:      url: "Employee/BulkUpload",
   8:      defaults: new { controller = "BulkUpload", action = "Index" }
   9:      );
  10:   
  11:      routes.MapRoute(
  12:          name: "Default",
  13:          url: "{controller}/{action}/{id}",
  14:          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  15:      );
  16:  }

2. 修改URL 引用

打開“~/Views/Employee”文件下的 AddNewLink.cshtml ,修改BulkUpload 鏈接,如下:

   1:   
   2:  <a href="/Employee/BulkUpload">BulkUpload</a>

3. 運行測試

關於實驗31

之前的URL 現在是否起作用?

是,仍然有用。BulkUploadController中的Index 方法可通過兩個URL 訪問。

1. ”http://localhost:8870/Employee/BulkUpload“

2. “http://localhost:8870/BulkUpload/Index”

Route 參數和Query 字符串有什么區別?

  • Query 字符串本身是有大小限制的,而無法定義Route 參數的個數。
  • 無法在Query 字符串值中添加限制,但是可以在Route 參數中添加限制。
  • 可能會設置Route參數的默認值,而Query String不可能有默認值。
  • Query 字符串可使URL 混亂,而Route參數可保持它有條理。

如何在Route 參數中使用限制?

可使用正則表達式。

如:

   1:  routes.MapRoute(
   2:      "MyRoute",
   3:      "Employee/{EmpId}",
   4:      new {controller=" Employee ", action="GetEmployeeById"},
   5:      new { EmpId = @"\d+" }
   6:   );

Action 方法:

   1:  public ActionResult GetEmployeeById(int EmpId)
   2:  {
   3:     ...
   4:  }

為了保證每個路徑參數都能獨立,因此參數名稱必須與Route Parameter一致。

是否需要將action 方法中的參數名稱與Route 參數名稱保持一致?

Route Pattern 也許會包含一個或多個RouteParameter,為了區分每個參數,必須保證action 方法的參數名稱與Route 參數名稱相同。

定義路徑的順序重要嗎?

有影響,在上面的實驗中,我們定義了兩個路徑,一個是自定義的,一個是默認的。默認的是最先定義的,自定義路徑是在之后定義的。

當用戶輸入“http://.../Employee/BulkUpload”地址后發送請求,UrlRoutingModule會搜索與請求URL 匹配的默認的route pattern ,它會將 Employee作為控制器的名稱,“BulkUpload”作為action 方法名稱。因此定義的順序是非常重要的,更常用的路徑應放在最后。

是否有什么簡便的方法來定義Action 方法的URL pattern?

我們可使用基於 routing 的屬性。

1.  基本的routing 屬性可用

在 RegisterRoutes 方法中在 IgnoreRoute語句后輸入代碼如下:

   1:  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   2:   
   3:  routes.MapMvcAttributeRoutes();
   4:   
   5:  routes.MapRoute(
   6:  ...

2. 定義action 方法的 route pattern

 

   1:  [Route("Employee/List")]
   2:  public ActionResult Index()
   3:  {

3. 運行測試

routing 屬性可定義route 參數,如下:

   1:  [Route("Employee/List/{id}")]
   2:  publicActionResult Index (string id) { ... }

IgnoreRoutes 的作用是什么?

當我們不想使用routing作為特別的擴展時,會使用IgnoreRoutes。作為MVC模板的一部分,在RegisterRoute 方法中下列語句是默認的:

   1:  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

這就是說如果用戶發送以“.axd”為結束的請求,將不會有任何路徑加載的操作,請求將直接定位到物理資源。


免責聲明!

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



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