SiteMap导航和查询字符串

目前我正在试图弄清楚如何将动态查询字符串参数添加到我的站点地图导航菜单。 例如,用户选择他想要使用的源和版本。 我有一个简单的站点地图,可以创建导航链接,但用户选择的参数需要在查询字符串中传递。 默认地图如下所示:

    

现在,链接需要根据用户选择的内容动态添加参数。 例如:

   

希望这是相当清楚的。 如果有人需要更深入的解释,请告诉我。

谢谢

不幸的是,默认情况下不支持此function。 但是您可以在Global.asax实现SiteMap.SiteMapResolve事件以捕获此类扩展的URL,并使用正确的url调用SiteMapProvider.FindSiteMapNode

 private void Application_Start(object sender, EventArgs e) { SiteMap.SiteMapResolve += ResolveCustomNodes; } private SiteMapNode ResolveCustomNodes(object sender, SiteMapResolveEventArgs e) { // catch ~/Image.aspx and ~/Headline.aspx if (e.Context.Request.AppRelativeCurrentExecutionFilePath.Equals( "~/Image.aspx", StringComparison.OrdinalIgnoreCase) || e.Context.Request.AppRelativeCurrentExecutionFilePath.Equals( "~/Headline.aspx", StringComparison.OrdinalIgnoreCase)) { string location = context.Request.QueryString["location"]; if (location != null) // ignore everything except location= return e.Provider.FindSiteMapNode( e.Context.Request.AppRelativeCurrentExecutionFilePath "?location=" + HttpUtility.UrlEncode(location)); } return null; // use default implementation; } 

无需自定义SiteMapProvider ,这适用于任何提供商。

现在,如果你想变得更有活力,你可以做几件事,例如(有可能):

使用与特殊属性匹配的部分查询字符串标记所有标记,并通过迭代整个站点地图来加载此列表。 这种方法的问题在于,对于某些站点地图提供商而言,这可能是非常低效的(基于文件的提供商是与这种方法很好匹配的提供商的示例)。 你当时要做的就是说

  

在代码中,您可以通过从根节点开始递归地找到这样的节点,并使用queryStringField属性记住所有节点:

 private IEnumerable FindNodesWithQueryString(SiteMapNode node) { if (node["queryStringField"] != null) yield return node; foreach (SiteMapNode childNode in node.ChildNodes) { foreach (SiteMapNode matchingNode in FindNodesWithQueryString(childNode)) { yield return matchingNode; } } } 

有了这个清单,有些人挥手,你应该能够做同样的伎俩。 请注意,您可能需要缓存此列表,因为可以比您期望的更频繁地调用SiteMapResolve事件。 特别是对于数据库类型的SiteMapProvider

 private SiteMapNode ResolveCustomNodes(object sender, SiteMapResolveEventArgs e) { string path = e.Context.Request.AppRelativeCurrentExecutionFilePath; foreach (var candidate in from node in FindNodesWithQueryString( SiteMap.RootNode) select new { Url = node.Url, UrlNoQuery = node.Url.Split('?')[0], QueryStringField = node["queryStringField"], Node = node } into x where path.Equals(x.UrlNoQuery, StringComparison.OrdinalIgnoreCase) select x) { string paramValue = context.Request.QueryString[ candidate.QueryStringField]; if (paramValue != null) { string url = candidate.UrlNoQuery + "?" + candidate.QueryStringField + "=" + HttpUtility.UrlEncode(paramValue); if (url.Equals(candidate.Url, StringComparison.OrdinalIgnoreCase)) return candidate.Node; } } return null; } 

ASP.NET中的默认SiteMap提供程序不允许使用查询字符串。

这是很多人遇到的问题 – 编写自己的提供程序很容易,但是它具有查询字符串function。

以下提供商已经为我好几年了。

http://www.csharper.net/blog/custom_sitemapprovider_incorporates_querystring_reliance.aspx

我有一个类似的问题与使用base64,url编码的字符串作为站点地图中的查询参数有关。 最简单的解决方案是只处理MenuItemDataBound事件并在那里进行编码:

  string[] url = e.Item.NavigateUrl.Split('?'); if (url.Length == 2) { url[1] = WebUtils.encodeString(url[1]); } e.Item.NavigateUrl = string.Join("?", url); 

我的webutils方法:

  public static string encodeString(string value) { return HttpUtility.UrlEncode(Convert.ToBase64String(Encoding.UTF8.GetBytes(value))); } public static string decodeString(string value) { return Encoding.UTF8.GetString(Convert.FromBase64String(HttpUtility.UrlDecode(value))); }