サイトマップと URL ルーティング
-
24-09-2019 - |
質問
ここで説明されているのと同様の質問があります。
WebForms による ASP.NET URL ルーティング - SiteMap の使用
私の ASP.Net WebForms Web アプリケーションには、次のようなサイトマップがあります。
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode title="Root">
<siteMapNode url="Home" title="Home" />
<siteMapNode url="Home?" title="Home" />
<siteMapNode url="Faq" title="FAQ" />
</siteMapNode>
<siteMapNode url="Reports" title="Your reports" />
<siteMapNode url="Reports?" title="Your reports" />
<siteMapNode url="ExtraReports" title="Extra reports" />
</siteMapNode>
<siteMapNode url="Presentations" title="Your presentations" />
<siteMapNode url="Presentations?" title="Your presentations" />
<siteMapNode url="ExtraPresentations" title="Extra presentations" />
</siteMapNode>
</siteMapNode>
URLを次の形式にしたいと思います。
://host/projects/{会社}/{プロジェクト番号}/Home
://host/projects/microsoft/10/Home
://host/projects/microsoft/11/Reports
://host/projects/apple/10/ExtraReports
URL ルーティングは、/projects/{company}/{projectno}/{pagename} を /Pages/{pagename}.aspx にルーティングします。
私のナビゲーションは上部のタブストリップで構成されており、そこには次の内容が含まれている必要があります ホーム、レポートとプレゼンテーション 左側のメニューとそのサブ項目 (例:「ホーム」を選択すると、次のようになります。 ホーム、よくある質問).
私の質問:
重複した SiteMapNode URL を処理する適切な方法は何ですか?
TabStrip が次のような URL を生成しないようにするにはどうすればよいですか:://host/Home と ://host/ExtraReports?
現在の会社とプロジェクトの選択を維持する必要があり、サイトマップは相対 URL を無視しますアクティブな選択を表示するには、TabStrip および Menu コントロールが選択された項目を認識する必要があります。これらすべてに対する適切な解決策は何でしょうか?
解決
これに数時間を費やした後、良い(十分:))解決策に到達したと思います。
サイトマップファイル
URL のないノードは親を指すことに注意してください。
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<siteMapNode>
<siteMapNode title="Home" url="Home">
<siteMapNode title="Home" />
<siteMapNode title="xxx" url="Cycle"/>
<siteMapNode title="yyy" url="Survey" />
<siteMapNode title="zzzteam" url="Team" />
</siteMapNode>
...
URLを生成するユーティリティクラス
CurrentContext は、RequestContext への静的参照です。
public static string GetPageUrl(SiteMapNode node) {
RouteValueDictionary values = new RouteValueDictionary(CurrentContext.RouteData.DataTokens);
values["page"] = node.Url.Trim('/');
return CurrentContext.RouteData.Route.GetVirtualPath(CurrentContext, values).VirtualPath;
}
MasterPage のデータバインドされたイベント
ナビゲーションは Telerik タブストリップ、サブナビゲーションは ASP.Net メニューです
private void navigation_TabDataBound(object sender, Telerik.Web.UI.RadTabStripEventArgs e) {
if (!String.IsNullOrEmpty(e.Tab.NavigateUrl)) {
SiteMapNode node = (SiteMapNode) e.Tab.DataItem;
// Is this tab a parent of the current navigation node? Then select it
if (SiteMap.CurrentNode.IsDescendantOf(node)) e.Tab.Selected = true;
e.Tab.NavigateUrl = XRouteHandler.GetPageUrl(node);
}
}
private void subNavigation_MenuItemDataBound(object sender, MenuEventArgs e) {
SiteMapNode itemNode = (SiteMapNode) e.Item.DataItem;
SiteMapNode currentNode = SiteMap.CurrentNode;
// SiteMapNodes without url will point to the parent node
if (String.IsNullOrEmpty(itemNode.Url)) {
itemNode = itemNode.ParentNode;
e.Item.Selectable = true;
}
// Is this menu item the node itself or one of it's parents? Then select it
if (currentNode == itemNode || currentNode.IsDescendantOf(itemNode))
e.Item.Selected = true;
e.Item.NavigateUrl = XRouteHandler.GetPageUrl(itemNode);
}
}
XmlSiteMapProvider の実装
現時点ではこのソリューションで十分ですが、後で検討して見た目を良くする予定です:)
public override SiteMapNode FindSiteMapNode(HttpContext context) {
string pageName = context.Request.Url.Segments.Last().Trim('/');
foreach (SiteMapNode node in SiteMap.RootNode.GetAllNodes())
if (node.Url.EndsWith(pageName, StringComparison.InvariantCultureIgnoreCase)) return node;
return SiteMap.RootNode;
}
他のヒント
Zyphax、
それはあなたのルートを考慮して再書き込みのTabStripとMenuコントロールする必要があるとしている可能性が最も高いです。これはまた、あなたが重複しSiteMapNodesを削除することができることを意味します。
その代わりに、ホーム・ページの子である遠い祖先を取得するためにサイトマップツリーを横断するために、いくつかのコードを記述する必要があります。これは、拡張メソッドであるかもしれない助けます。
public SiteMapNode FurthestAncestor(this SiteMapNode node)
{
while (node.Key != this.RootNode.Key && node.ParentNode.Key != this.RootNode.Key)
{
node = node.ParentNode;
}
return node;
}
また、を支援する相対URLを使用して../プレゼンテーションのではなく、の/プロジェクト/りんご/ 10 /プレゼンテーションの