ASP.NET MVC 原理及路由)

來源:互聯網
上載者:User
  

前言

在上一篇文章中,我們實現了第一個ASP.NET MVC頁面。對於沒有接觸過這個架構的朋友來說,可能對有些地方會迷惑,所以這篇文章我將通過圖示配合文字的方法,站在全域的角度介紹一些ASP.NET MVC的運行機制,這樣可以協助朋友們更好的理解後續文章。

全域

首先我們來看一副圖片,由於這幅圖是我自己畫的,不是摘自微軟官方,所以如果有什麼不到位的地方還望海涵!

首先,使用者通過Web瀏覽器向伺服器發送一條url請求,這裡請求的url不再是xxx.aspx格式,而是http://HostName/ControllerName/ActionName/Parameters的樣子。這個請求被ASP.NET MVC的路由映射系統截獲。(路由映射可以在Global.asax中配置,我們一會再說)路由映射系統按照映射規則,解析出控制器名ControllerName,Action名ActionName和各個參數Parameters,然後,找尋Controllers目錄下的ControllerNameController.cs這個控制器類,預設情況下,系統總是找尋Controllers目錄下的“控制器名+Controller”這麼一個類,然後,找尋這個類下與ActionName同名的方法,找到後,將Parameters作為參數傳給這個方法,而後Action方法開始執行,完成後返回相應視圖,預設情況下,會返回Views目錄下與ControllerName同名的目錄下的與ActionName同名的aspx檔案,並且將ViewData傳遞到視圖。ViewData中一般包含了控制視圖顯示的控制量以及視圖顯示需要的資料。

我們按以上思路回顧一下上一篇中首頁的請求過程。我們傳遞的url是http://localhost/Home/Index。預設路由規則下,將ControllerName設為“Home”,ActionName設為“Index”,沒有參數。於是系統找尋Controllers目錄下的HomeController類的Index方法,成功找到,於是執行之。這個方法調用Mock的Model取出一些資料,放入ViewData相應索引值項裡。然後返回視圖,返回的是Views下Home下的Index.aspx。這個視圖取出ViewData中的資料按照一定格式呈現,於是完成了一次典型的ASP.NET MVC調用。

路由

從上面可以看出,ASP.NET MVC中路由是很重要的。它直接決定了如何解析url,因此決定了系統如何工作。那麼,下面我們來揭開路由神秘的面紗。

開啟我們Demo下的Global.asax.cs檔案,可以看到如下代碼:

Global.asax.cs:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCDemo
{
// 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);
}
}
}

 

我們揀重點說。注意上面有個routes.MapRoute方法。這個方法的作用是向系統增加一條路由規則。這裡唯一的一條規則是系統預設增加的,第一個參數是規則名,是一個一般字元串。關鍵是第二個參數,它也是一個字串,但是它描述了如何解析url。可以這樣理解,它描述了url串HostName後面部分如何匹配,其中帶{}的表示參數匹配,如果不帶則表示字串匹配。

例如,上面的{controller}/{action}/{id}表示如果HostName後面有三段由“/”分割的字串,則這個url被匹配,並且分別被解析成控制器名,Action名和一個叫“id”的參數。如果你輸入的是http://localhost/Home/Index/1則後面的“1”將被當做參數id的值,但是如果你請求http://localhost/Home/Index/1/2,抱歉,你的請求無法成功,因為這條路由規則沒法匹配你的url,因為你的HostName後面有四段,而這個路由規則只能匹配三段的。

也許你還注意到一個問題,http://localhost/Home/Index明明HostName後面只有兩段,怎麼也被匹配了呢?這就是MapRoute方法的第三個參數起作用了。這個參數的作用是為上面規則中各個{}匹配段設定預設值,如上,id的預設值為"",即空。所以在http://localhost/Home/Index中,雖然沒有顯示指定id,但是它依然可以匹配成功,預設作為空白值。如果你把其中id=""去掉,你會發現http://localhost/Home/Index已經無法匹配了。依次類推,http://localhost/Home/也可以匹配成功,因為{action}預設是Index,http://localhost/也可以匹配成功,因為預設{controller}為Home,所以,在這條預設值下http://localhost/Home/Index和http://localhost/是等效的。

綜上分析,我們得出一條重要結論:在預設值被設定的情況下,映射規則“配少不配多”,少的部分由預設值代替。

上面的匹配規則中,三個匹配段都帶大括弧的,都是參數匹配,下面我們來說說強字串匹配。例如,我們有一個url需要這樣http://localhost/Category/Detail/Name。如果按照上面的匹配規則,Name段的值會被匹配到id中去,可是我們想在CategoryController的Detail方法中使用名叫“name”的參數而不是使用名叫“id”的參數,怎麼辦呢?很簡單,我們增加一下一條匹配規則:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCDemo
{
// 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(
"Category",                                              // Route name
"Category/Detail/{name}",                           // URL with parameters
new { controller = "Category", action = "Detail", name = "" }  // Parameter defaults
);
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);
}
}
}

 

可以看到,我們在預設規則前增加了一條規則,其中其中控制器名和Action名不再是參數,而變成了強字串(沒有{})。這時,當我們請求的url是http://localhost/Cateogry/Detail/para的形式時,就會直接匹配新加的規則,而para的值不會被賦給成id而是賦給名叫name的變數。

需要注意的是,我們新的路由規則一定要放在前面,因為ASP.NET MVC會自上向下匹配第一條找到的可匹配路由規則。

視圖

說完了路由規則,我們再來說說視圖。

上面說道,Action方法傳回型別是ActionResult,其實這個傳回型別不局限於View方法返回ViewResult,它還有很多實現,這裡列舉幾個。

ViewResult:一般呈現某個aspx檔案,由View方法返回。

RedirectToResult:使瀏覽器重新導向,由Redirect方法返回。

RedirectToRouteResult:直接交給下一個Action,由RedirectToAction方法返回。

還有幾個,先不說了,因為後續文章基本用不到其他的,關於那幾個以後朋友們可以自己看相關資料。

小結

看完這篇文章,就基本把90%的障礙掃清了。下面的文章中,將繼續我們的執行個體。在下一篇中,我們來完成發布公告的功能,看看ASP.NET MVC下如何處理表單資訊的傳遞。

本文出自張洋部落格T2's Notebook

【編輯精選】

  1. ASP.NET MVC案例教程(一)
  2. ASP.NET MVC案例教程(二)
  3. ASP.NET MVC案例教程(四)
  4. ASP.NET MVC案例教程(五)
  5. ASP.NET MVC案例教程(六)
  6. ASP.NET MVC案例教程(七)


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.