HtmlHelper是MVC中新的而且很好用的物件,我們可以用來產生很多延伸的各種Helpers,其中HtmlHelper.GenerateRouteLink()可以用來產生網頁上很單純Link的HTML碼。
如<a href="http://myWebSite/Product/Browse" >產品瀏覽</a>
而本文就是利用HtmlHelper.GenerateRouteLink來達到上述產生Link需求,也藉此說明HtmlHelper.GenerateRouteLink()的使用方式。
From:www.lamborghini.com
在MVC的應用中,我們常會用到需要由程式產生一個Link,而這個Link可由MVC中的Route判別該存取哪一個頁面,例如有一個「賀瑞斯汽車資訊網站」,需要在網頁上產生一個Link,可讓網友點選後,即可連結到產品名稱為Lamborghini的汽車規格資訊頁面。
網址列上我們希望如下顯示:
http://localhost/Product/Details/CarName/Lamborghini
我們當然可以直接以HTML寫成下列的Link:
<a href="http://localhost/Product/Details/CarName/Lamborghini" >藍寶堅尼</a>
但想像一下,假設「賀瑞斯汽車資訊網站」需提供好幾百種車款的詳細資訊,若都是在網頁上直接以HTML寫成好幾百條Link程式碼,這看來不是一件有效率的事,而且維護起來是一件災難。比較適當的方式,就是透過程式與資料庫互動,動態且自動產生很多這類的連結資訊。透過程式與資料庫互動的方法其中之一是我們可以用foreach迴圈方式去讀取資料中Model。CarName的方式,也可以組成很多如下Link,如下。
<a href="http://localhost/Product/Details/CarName/Lamborghini" >藍寶堅尼</a>
網址顯示 http://localhost/Product/Details/CarName/Lamborghini
<a href="http://localhost/Product/Details/CarName/Porsche" >保時捷</a>
網址顯示 http://localhost/Product/Details/CarName/Porsche
另外也可以利用本文所提的HtmlHelper.GenerateRouteLink()的方式,達到上述產生Link需求,尤其是要寫MVC中各種Helpers.GenerateRouteLink()這個方法更是重要。
下面簡單說明GenerateRouteLink所需帶入的各參數與涵義,並舉例說明實際用法讓大家瞭解。
GenerateRouteLink方法
GenerateRouteLink(RequestContext requestContext,
RouteCollection routeCollection,
string linkText,
string routeName,
RouteValueDictionary routeValues,
IDictionary(String, Object) htmlAttributes)
RouteCollection routeCollection,
string linkText,
string routeName,
RouteValueDictionary routeValues,
IDictionary(String, Object) htmlAttributes)
下面為GenerateRouteLink需帶入的參數說明,這些來自微軟MSDN文件,不過很可惜,沒有實際範例可供參考,這也是本文想要補足之處。
requestContext
型別:System.Web.Routing..::..RequestContext
HTTP 要求的內容。
routeCollection
型別:System.Web.Routing..::..RouteCollection
URL 路由的集合。
linkText
型別:System..::..String
要顯示的連結文字標題。
routeName
型別:System..::..String
用來傳回虛擬路徑之路由的名稱。
routeValues
型別:System.Web.Routing..::..RouteValueDictionary
包含路徑參數的物件。
htmlAttributes
型別:System.Collections.Generic..::..IDictionary<(Of <(<'String, Object>)>)>
物件,包含項目的 HTML 屬性。
傳回值
型別:System..::..String
HTML 項目,連結至指定的 URL 路由。
型別:System.Web.Routing..::..RequestContext
HTTP 要求的內容。
routeCollection
型別:System.Web.Routing..::..RouteCollection
URL 路由的集合。
linkText
型別:System..::..String
要顯示的連結文字標題。
routeName
型別:System..::..String
用來傳回虛擬路徑之路由的名稱。
routeValues
型別:System.Web.Routing..::..RouteValueDictionary
包含路徑參數的物件。
htmlAttributes
型別:System.Collections.Generic..::..IDictionary<(Of <(<'String, Object>)>)>
物件,包含項目的 HTML 屬性。
傳回值
型別:System..::..String
HTML 項目,連結至指定的 URL 路由。
重點來了,再提一下,我們是要建立一個HtmlHelpers中的GenerateRouteLink()。如何建立一個HtmlHelpers就暫時不在這裡討論了,大家可到微軟:建立Custom HTML Helpers參考一下基本建立方式。建立HtmlHelpers內的GenerateRouteLink()來自動產生如下這樣的Link,這才是本文所要說明的地方。
http://localhost/Product/Details/CarName/Lamborghini
而每一個參數,我們可實際以下列方式帶入:
requestContext參數:就是指HTTP要求的內容,我們可帶入「helper.ViewContext.RequestContext」。
routeCollection參數:就是指Route的集合,我們可帶入「helper.RouteCollection」,因為這部份是提供給Route使用,故直接帶入這些值即可。
linkText參數:就是Link要出現的文字,在我們「賀瑞斯汽車資訊網站」的例子中,我們要顯示「Lamborghini(藍寶堅尼)汽車規格資訊」這個字串。
string myLinkName= "Lamborghini(藍寶堅尼)汽車規格資訊";
routeName參數:就是我們「必須」寫在Global.asax中,讓網站系統的Route「識別的名稱」,說穿了就是一個字串型態的文字,我們設定如下:
string myRouteName = "CarProducts";
有了這個「識別的名稱」,這樣她(Route)才知道要去使用Global.asax內那組「Route的規則」來處理這條Link要指到哪一個Controller與Action,而在Global.asax內,我們也需加上這組「Route的規則」,讓整串Link產生後,網友在網頁上點選才能真正去執行。這組規則如下。
routes.MapRoute(
"CarProducts", // Route name
"Product/Details/CarName/{car_name_id}", // URL with parameters
new { controller = "Product", action = "Details" } // Parameter defaults
);
"CarProducts", // Route name
"Product/Details/CarName/{car_name_id}", // URL with parameters
new { controller = "Product", action = "Details" } // Parameter defaults
);
routeValues參數:routeValues資料型態是一個<Key,Value>的組合,這個也會在Global.asax中被使用到,就是上述Global.asax中參數car_name_id(就是指Key)與屆時需帶入的資料(就是指Value),以我們「賀瑞斯汽車資訊網站」為例,我們可先直接帶入<"CarName","Lamborghini">這樣的組合。
RouteValueDictionary myRouteValues = new RouteValueDictionary();
myRouteValues.Add("car_name_id",("Lamborghini"));
myRouteValues.Add("car_name_id",("Lamborghini"));
若是CarName後要帶數值型態的編號:38,也可用下列方式:
myRouteValues.Add("car_name_id",(38));
但是一般我們會自資料庫抓了汽車名稱或編號資料,放入陣列中,讓程式自動產生routeValues中所需的value,如下:
myRouteValues.Add("car_name_id",carNameIDAry[i]);
htmlAttributes參數:就是我們舉例的「http://localhost/Product/Details/CarName/Lamborghini」這個Link要配合名為「car-link-style」的這個cssClass,如下寫法:
IDictionary<string, object> myHtmlAtts= new Dictionary<string, object>();
myHtmlAtts.Add("class", "car-link-style");
myHtmlAtts.Add("class", "car-link-style");
或是myHtmlAtts後面直接加上style的各種屬性設定如下寫法:
myHtmlAtts.Add("style", "color:Gray;font-family:Georgia;font-size:20px");
上面已經設定完GenerateRouteLink()所需帶入的各種參數,本範例完整方法與參數呼叫如下,她會回應成一個網頁上的Link字串供網友點選,就是一直在提的「http://localhost/Product/Details/CarName/Lamborghini」。
public static string ShowDetailCar(this HtmlHelper helper)
{
:
:
return HtmlHelper.GenerateRouteLink(helper.ViewContext.RequestContext,
helper.RouteCollection,
helper.Encode(myLinkName),
helper.Encode(myRouteName),
myRouteValues,
myHtmlAtts);
}
{
:
:
return HtmlHelper.GenerateRouteLink(helper.ViewContext.RequestContext,
helper.RouteCollection,
helper.Encode(myLinkName),
helper.Encode(myRouteName),
myRouteValues,
myHtmlAtts);
}
而上面這個Link產生後,它會對應到Product這個Controller的Details這個Action,在這個Action中,我們可簡單寫成直接給予一個Car的資料,當然Car這個類別須在Models中建立。在正式的網站中,通常Car的資料是從資料庫撈出來的,然後轉成List<Car>的資料.這裡只是示範一筆資料來顯示。注意帶入Details這個Action的參數,名稱要和上述routeValues<Key,Value>參數內的Key值相符合(這裡就是都要名稱為car_name_id),也要和Global.asax內那組我們用到的「識別的名稱」內的參數相同名稱。
public class ProductController : Controller
{
public ActionResult Details(string car_name_id)
{
Car carToDetails = new Car
{
CarName = "Lamborghini Gallardo",
Year = "2004",
Country = "義大利",
Exhaust = "4961 cc",
Speed = "309 km/h"
};
return View(carToDetails);
}
}
{
public ActionResult Details(string car_name_id)
{
Car carToDetails = new Car
{
CarName = "Lamborghini Gallardo",
Year = "2004",
Country = "義大利",
Exhaust = "4961 cc",
Speed = "309 km/h"
};
return View(carToDetails);
}
}
實際執行後,自動產生的Link如下第一個圖,點選該Link後,就顯示該車的詳細資料,如下圖二。我們可以看一下圖中網址列的Link,就會直接指到我們本範例中所想建立的「http://localhost/Product/Details/CarName/Lamborghini」這樣型態的連結。
小結
網址上顯示「http://localhost/Product/Details/CarName/Lamborghini」這樣的名稱,看來比顯示「http://localhost/Product/Details.aspx?CarName=Lamborghini」還要來得直覺與簡便,這部份也可利用在顯示分頁資料的分頁頁碼字串中,如下:
直覺與相互獨立,這就是ASP.NET MVC2的魅力所在!!
沒有留言:
張貼留言