顯式運算式使開發人員對包含本地資源的檔案和資源鍵(resource key)的名稱有更強的控制能力。在樣本web.sitemap中,第一個元素使用了顯式資源運算式。顯式運算式在每個屬性上指定。第一個元素的Title屬性使用了顯式運算式。顯式運算式必須以$resource:開頭。在這個標識符之後,開發人員必須提供資源檔的根名稱和資源鍵。開發人員可以選擇提供一個預設值。在例子中,運算式$resources: Title, MyTitle , Home表明提供者應該查看以"Title"開頭的資源檔。對於發送法語頭資訊的瀏覽器開說,提供者會尋找Title.fr.resx資源檔。接下來提供者查看鍵為MyTitle的資源。如果提供者無法找到這種資源,它會把字串"Home"作為預設值。
你可以運行樣本來查看網站地圖本地化的效果。把英語作為預設語言的瀏覽器會顯式英語文本。如果使用IE,你可以通過點擊"工具->Internet選項",並在"通用"選項卡點擊"語言"按鈕,點擊"添加"按鈕並選擇添加"法語"。如果需要,還需要選中法語並點擊"向上移動"按鈕,使它成為IE的預設請求語言。把預設的語言改成法語之後,重新整理樣本頁面。請注意,Menu、Treeview和SiteMapPath控制項中的文本自動地顯式為App_GlobalResources目錄中存放的法語資源檔中的法語文本。
Web.sitemap的內容
以下是引用片段:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">
<siteMapNode url="~/Default.aspx" title=" $resources: Title, MyTitle , Home" description="Default page description when no localized value exists." >
<siteMapNode url="~/Category.aspx" resourceKey="Category">
<siteMapNode title="Autos" description="Autos" url="~/Autos.aspx" resourceKey="Autos" />
<siteMapNode title="Games" description="Games" url="~/Games.aspx" resourceKey="Games" />
<siteMapNode title="Health" description="Health" url="~/Health.aspx" resourceKey="Health" />
<siteMapNode title="News" description="News" url="~/News.aspx" resourceKey="News" />
</siteMapNode>
</siteMapNode>
</siteMap>
修改提供者(Provider)返回的網站導覽資料
儲存在web.sitemap中、供XmlSiteMapProvider使用的導航資料是靜態--這些資料被載入記憶體中並作為唯讀資料存放區。但是,很多網站的導航結構是根據查詢字串的值來參數化的。例如,新聞群組(newsgroup)網站可能擁有良好定義的頁面結構(例如,首頁、新聞類別頁面和新聞內容頁面),但是實際的內容可能會有很大的不同,這依賴於查詢字串中的標識符。儘管把每種可能的查詢字串值都儲存在元素中也是可能的,但是即使是中等數量的查詢字串值,也要求sitemap檔案包含數百個元素。
網站導覽特性在SiteMapProvider基類中暴露了SiteMapResolve事件。可以使用SiteMap.SiteMapResolve或直接使用提供者SiteMap.Provider.SiteMapResolve來執行這個事件。這個事件的傳回值是一個SiteMapNode執行個體。你可以在自己的事件處理常式中編寫自訂邏輯來建立SiteMapNode執行個體的階層。這個邏輯可以修改每個SiteMapNode的屬性,因此URL和Title等屬性會反映查詢字串帶有的資料資訊。
下面的例子在global.asax中註冊了一個事件處理常式。這個事件處理常式的代碼是App_Code目錄中的一個類。這個自訂的類複製與當前頁面對應的SiteMapNode執行個體。XmlSiteMapProvider返回的節點都是唯讀,而調用SiteMapNode上的Clone方法返回的是可寫入的節點。在執行個體中,如果給Clone傳遞了true值,將導致當前的SiteMapNode和它的所有父節點都是可寫入的。這個類的代碼的其它部分檢查當前的頁面和當前頁面的查詢字串,確定當前頁面位於網站階層的什麼位置。代碼修改了URL和Title屬性,包含一些額外的資訊,這樣SiteMapPath控制項顯示的導航UI就反映了網站使用者為到達當前頁面的實際點擊路徑。
運行樣本的時候,你開始位於網站的首頁。SiteMapPath控制項也反映了這一點。點擊任何連結都會帶你進入分類頁面,它顯示相關新聞類別中的新聞連結。請注意,如果你把滑鼠停留在SiteMapPath控制項的最後一個連結上,瀏覽器狀態列中顯示的URL包含了查詢字串資訊(它指定了新聞類別)。點擊任何一個發布連結都會把你帶回到新聞發佈頁面。如果你把滑鼠停留SiteMapPath控制項的連結上,可以注意到控制項中的最後兩個連結帶有的URL和Title包含了點擊路徑的正確查詢字串和描述資訊。如果你導航到網站的首頁,並點擊其它的新聞群組和內容連結,SiteMapPath控制項會被更新並反映第二次點擊的連結。
以下是引用片段:
Public Class PathExpansionHandler
Public Shared Function ExpandPath(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
'擷取當前和之前節點的引用
Dim nodeCopy As SiteMapNode = SiteMap.CurrentNode.Clone(True)
Dim tempNode As SiteMapNode = nodeCopy
'Check if there is a newsgroup type in the query string
Dim typeID As String = Nothing
Dim typeIDUrlEncoded As String = Nothing
If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then
typeID = e.Context.Server.HtmlEncode(e.Context.Request.QueryString("type"))
typeIDUrlEncoded = e.Context.Server.UrlEncode(e.Context.Request.QueryString("type"))
End If
'首先執行發佈頁面URL的固定
'如果查詢字串中包含發布ID,我們就知道當前節點式發佈頁面
If Not String.IsNullOrEmpty(e.Context.Request.QueryString("postingID")) Then
Dim postingID as string = _
e.Context.Server.HtmlEncode(e.Context.Request.QueryString("postingID"))
Dim postingIDUrlEncoded as string = _
e.Context.Server.UrlEncode(e.Context.Request.QueryString("postingID"))
Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded + "&postingID=" + postingIDUrlEncoded
Dim NewTitle As String = tempNode.Title + ": " + postingID
tempNode.Url = NewUrl
tempNode.Title = NewTitle
tempNode = tempNode.ParentNode
End If
'然後,對新聞群組頁面進行固定
'這時候nodeCopy 變數知賢了新聞群組節點
If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then
Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded
Dim NewTitle As String = tempNode.Title + ": " + typeID
tempNode.Url = NewUrl
tempNode.Title = NewTitle
End If
'最後返回當前節點
Return nodeCopy
End Function
End Class