系列目錄
URL是如何通過路由表產生的(outbound)
通常我們被推薦在view設計時使用Html.ActionLink(…)產生連結,這樣做的優勢就是,url可以根據路由表產生。路由機制的另一個職責便是根據路由表產生url,而不是由我們手動編寫。接下來深入分析一下其原理。
類似Html.ActionLink的方法,最終都將通過查詢路由表來產生url,跟inbound一樣,路由表總是按順序被依次遍曆,直到匹配。每個Route的GetVirtualPath方法負責審查,該方法接受一個RouteValueDictionary參數,該參數實際上就是由相應的Helper提供的。當以下三個條件成立時,認為匹配成功:
一、每個由大括弧定義的參數必須能夠找到對應的值。按照優先順序這些值將有下面三種來源:
1.RouteValueDictionary參數明確提供的。也就是我們在調用某些有產生url功能的Helper時提供的,比如ActionLink方法;
2.*從當前請求的內容相關的RouteData中;關於這點有更特殊的情況,下面將詳細討論;
3.Route的Defaults中。
二、如果每個Defaults集合中的參數與RouteValueDictionary參數中的值都符合,而且這些值沒有在url pattern中用大括弧定義,那麼認為匹配。聽起來有點拗口,下面舉個例子.
假如有如下規則:
routes.MapRoute( null, "manage/orders/{page}", new { controller = "Admin", action = "OrderManage", page = UrlParameter.Optional });
頁面有如下連結:
<a href="<%:Url.Action("OrderManage", "Admin") %>">Order</a>
最後產生的連結將是這樣的(這裡省略了前面的domain):
<a href="…/manage/orders">Order</a>
Defaults中有兩個參數controller和action,在url的pattern中沒有類似{controller}和{action},而且Url.Action的參數同時提供了與Defaults設定一致的參數值(這已經夠了),於是這個url是匹配的。
三、每個參數都符合Constraints的匹配規則。
滿足上面三個條件後,GetVirtualPath就會將相應的參數填入url中,並最終返回url的字串。需要強調的一點是:MVC架構的這種行為工作在懶惰模式下,一旦“該要的要到了”,那麼就停止繼續遍曆。這也從另一個角度說明了,把特殊的往前放的黃金原則。
舉個例子:
下面是兩個有順序的Route:
routes.MapRoute( null, "manage/car", new { controller = "Admin", action = "Car" } );routes.MapRoute( null, "manage/car/{operation}", new { controller = "Admin", action = "Car" } );
有一個連結資料表示:
<%: Html.ActionLink("Add Car", "Car","Admin", new { operation = "add" }, null )%>
最後的結果是什麼呢?是manage/car/add嗎?
其實最後的結果是manage/car,為什麼呢?對於第一個Route,它期望的是controller和action這兩個參數,而上面的ActionLink的確完整的提供了這兩個參數,而且與Defaults設定一致(這滿足規則的第二條),於是匹配了!即使還提供了operation參數,架構也不管了。顯然這不是希望的。只要把兩個Route的位置換一下即可。這個例子只是一個示範。
*關於上麵條件一的第二小點,其實是個很棒的特性,這裡補充一個例子:
假設當前頁面的url是:/Catalog/List/Purple/123
routes.MapRoute(null, "{controller}/{action}/{color}/{page}");
<%: Html.ActionLink("Click me", "List", "Catalog", new {page=789}, null) %>
這個link能匹配這個route嗎?也許你認為我沒有提供color參數啊,怎麼能匹配呢?事實上,結果確出人意料的是:
<a href="/Catalog/List/Purple/789">Click me</a>
因為當前頁面是/Catalog/List/Purple/123,此時的RouteData儲存了color參數值,儘管在ActionLink中沒有顯示設定color,但是仍然從當前的RouteData中找到了color參數。
再看一個例子:
當前頁面的url還是:/Catalog/List/Purple/123
routes.MapRoute(null, "{controller}/{action}/{color}/{page}");
<%: Html.ActionLink("Click me", "List", "Catalog", new {color="Aqua"}, null) %>
這個link還能匹配這個route嗎?也許你認為根據上面的規則應該能,但結果卻是無法匹配,為什麼呢?因為有個原則,RouteData中的資料只能用於填充url pattern中“靠前的參數”,最後一個參數是不能的!
最後關於outbound還有一個原則,Defaults提供的值,會儘可能的不出現在最終的url結果中。
URL設計原則
在MVC架構下,我們可以對URL做完全的控制,自然就想到要設計出優良的url,URL究竟該如何設計。由於本人web開發經驗很少,以下是書中的內容,我做了些概括:
1.url要盡量通俗易懂,不要把技術的東西包含在裡面,比如下面這樣的:
/Website_v2/CachedContentServer/FromCache/AnnualReport
/my%20great%20article(使用/my-great-article為好)
2.有意義的文本總比ID數字讓人感覺舒服
3.不要在url中帶有尾碼名
4.要有比較強的層次感,又要簡短易記,比如:/Products/Menswear/Shirts/Red
5.url要大小寫不敏感,並且盡量使用小寫字母,mvc架構是大小寫不分的
6.不要因為url的變更而棄用老的url,要使用跳轉的方式
7.對於唯讀操作使用get方式,對於要修改伺服器資料的請求使用post方式;url要方便人們儲存書籤或分享網頁,因此,對於分頁顯示的情況,分頁要體現在url中
8.QueryString要盡量少用。當參數是為了參與某種演算法,而不是為了直接的資源指向時,可以使用QueryString,因為使用者此時不願意手動輸入url。比如page參數
301和302
同樣是使用戶端瀏覽器跳轉,301是暗示永久跳轉,可以暗示搜尋引擎這個url將永久不用,當確實需要更形url時考慮;
302表示臨時跳轉,MVC的RedirectToRouteResult和RedirectResult使用302。
可以像下面這樣進行301跳轉:
public static class PermanentRedirectionExtensions{public static PermanentRedirectToRouteResult AsMovedPermanently(this RedirectToRouteResult redirection){return new PermanentRedirectToRouteResult(redirection);}public class PermanentRedirectToRouteResult : ActionResult{public RedirectToRouteResult Redirection { get; private set; }public PermanentRedirectToRouteResult(RedirectToRouteResult redirection){this.Redirection = redirection;}public override void ExecuteResult(ControllerContext context){// After setting up a normal redirection, switch it to a 301Redirection.ExecuteResult(context);context.HttpContext.Response.StatusCode = 301;}}}
public ActionResult MyActionMethod(){return RedirectToAction("AnotherAction").AsMovedPermanently();}
關於SEO(search engine optimization)
提高排名的技巧:
1.url使用關鍵字而不是數字
2.url使用較少的QueryString,不要使用底線
3.單一內容單一url,不要多個url指向相同的內容
4.如果要多個url指向相同的內容,使用301跳轉
5.網頁的內容要可被“定址”,要使用get方式,內容不要過於依賴post方式,或者js,flash,silverlight等用戶端技術。
勞動果實,轉載請註明出處:http://www.cnblogs.com/P_Chou/archive/2010/11/08/details-asp-net-mvc-03.html