深入理解ASP.NET MVC(2)

來源:互聯網
上載者:User

 

系列目錄

請求是如何進入MVC架構的(inbound)

當一個URL請求到來時,系統調用一個註冊的IHttpModulesUrlRoutingModule它將完成如下工作

一、在RouteTable.Route中從第一個Route開始尋找第一個匹配當前URL的Route。需要同時滿足下面的條件,才能算匹配:

1.URL匹配Route屬性中Url的模型;

2.所有{}中定義的參數都可以在請求的URL中找到對應,或者參數在Route的Defaults中也有定義,當然Defaults中定義優先順序低於URL中的定義,亦或者參數被設定成UrlParameter.Optional

3.參數滿足Route的Constraints定義的匹配規則,規則可能是一個正則式,或是一個IRouteConstraint對象。

二、指定匹配的RouteBase將通過GetRouteData方法提供一個RouteData結構,RouteData包含如下四個屬性:

1.Route:Route對象自己;

2.RouteHandler:一個實現了IRouteHandler的對象,MVC提供一個MvcRouteHandler類,從MapRoute的源碼可以看出,總由MvcRouteHandler擔任這個角色。MvcRouteHandler知道如何從RouteData中尋找Controller和Action。事實上MvcRouteHandler會尋找索引值為"controller"和"action"參數,所以我們永遠需要包含"controller"和"action"兩個參數;

3.Values:儲存URL中參數的值字典,參數包括{}定義的,Route.Defaults中的,以及從QueryString中獲得的;

4.DataTokens:一個附加的字典,主要用於Areas機制,以後會詳細討論。

註:如果GetRouteData返回null的話,就無法進入MVC架構,常見的情況是有直接的靜態物理檔案能夠匹配這個url,通常是一些資源檔,如css,image等檔案。可以通過設定RouteCollection的RouteExistingFilestrue,使得用於不匹配靜態檔案(注意true是不匹配,這個命名和奇怪)。下面的代碼是GetRouteData中的程式碼片段,說明了這一機制是如何?的。

    if (!this.RouteExistingFiles)    {        string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath;        if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath)))        {            return null;        }    }

三、調用RouteData中的RouteHandler,同時為RouteHandler提供包括RouteDataHttpContextBase對象等上下文變數,並封裝成一個叫requestContext的參數傳遞給RouteHandler。如果使用MvcRouteHandler,那麼至此,就進入了MVC架構

 

幾點注意點:

1.由於上面提到的UrlRoutingModule的搜尋行為,Route在RouteCollection中添加的順序就十分重要了。記住:優先添加形式特殊的Route

2.MvcRouteHandler在調用Controller的Action的時候會自動為Action提供參數。參數來源於RouteData的索引值對,MvcRouteHandler會自動將鍵名和Action的參數名比較,這種比較是大小寫敏感的,所以在Action中寫參數名的時候要注意了,關於這點以後會詳細展開;

3.如果希望URL中的參數是可選的,要設定參數為UrlParameter.Optional。

 

自訂參數匹配規則

Route的Constraints定義URL中參數匹配規則,規則可能是一個正則式,或是一個IRouteConstraint對象。熟悉的情況是,通過MapRoute的簡化API設定Constraints為一個正則式。但如果我們的匹配規則較複雜呢?事實上,我們可以自己實現一個IRouteConstraint對象,IRouteConstraint只有一個Match方法,所以並不困難。我之前一篇文章ASP.NET MVC的全球化方案中有一個IRouteConstraint的實現。

還有個例子,MVC架構有個HttpMethodConstraint實現了IRouteConstraint,我們可以像下面這樣使用:

routes.MapRoute(null, "Articles/{id}", new { controller = "Articles", action = "Show" }, new { httpMethod = new HttpMethodConstraint("GET") } );

這表示只有以GET方式請求的URL才能匹配這個Route。需要注意的是,我們常常會在Action上加上[HttpGet]或[HttpPost]來做類似的限定,但兩者完全不同,這裡的限定是在MVC架構外的,而[HttpGet]是在架構內的,顯然這種方法高效些。

勞動果實,轉載請註明出處:http://www.cnblogs.com/P_Chou/archive/2010/11/02/details-asp-net-mvc-02.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.