C# 站点地图导航和查询字符串
目前,我正在尝试找出如何将动态查询字符串参数添加到我的站点地图导航菜单中。例如,用户选择要使用的源和版本。我有一个简单的站点地图,可以创建导航链接,但是需要在查询字符串中传递用户选择的参数。默认贴图如下所示:C# 站点地图导航和查询字符串,c#,asp.net,dynamic,sitemap,C#,Asp.net,Dynamic,Sitemap,目前,我正在尝试找出如何将动态查询字符串参数添加到我的站点地图导航菜单中。例如,用户选择要使用的源和版本。我有一个简单的站点地图,可以创建导航链接,但是需要在查询字符串中传递用户选择的参数。默认贴图如下所示: <siteMapNode url="" title="" description="" > <siteMapNode url="~/Image.aspx?location=Our Products" title="Our Products" description
<siteMapNode url="" title="" description="" >
<siteMapNode url="~/Image.aspx?location=Our Products" title="Our Products" description="Our Products" />
<siteMapNode url="~/Headline.aspx?location=Our Authors" title="Our Authors" description="Our Authors" />
</siteMapNode>
现在链接需要根据用户选择的内容动态添加参数。例如:
<siteMapNode url="~/Image.aspx?location=Our Products&Source=12345&Edition=asdfff" title="Our Products" description="Our Products" />
<siteMapNode url="~/Headline.aspx?location=Our Authors&Source=12345&Edition=asdfff" title="Our Authors" description="Our Authors" />
希望这是相当清楚的。如果有人需要更深入的解释,请告诉我
谢谢很遗憾,ASP.NET中的默认站点地图提供程序不允许查询字符串 这是许多人遇到的一个问题——编写自己的具有查询字符串功能的提供者非常容易 下面的提供者已经为我工作了好几年
不幸的是,默认情况下不支持此功能。但是,您可以在
Global.asax
中实现SiteMap.SiteMapResolve
事件以捕获此类扩展url,并使用正确的url调用SiteMapProvider.findsitemasnode
:
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
s,这适用于任何提供商
现在,如果你想变得更有活力,你可以做几件事,例如(可能有几种方法):
使用与特殊属性匹配的部分查询字符串标记所有
标记,并通过迭代整个站点地图加载此列表。这种方法的问题是,对于某些站点地图提供程序来说,这可能非常低效(基于文件的提供程序就是一个很好地匹配这种方法的提供程序示例)。然后你会说这样的话
<siteMapNode url="~/Image.aspx?location=Our Products"
queryStringField="location"
title="Our Products" description="Our Products" />
有了这份清单,再加上一些挥手的动作,你应该也能做到这一点。请注意,您可能需要缓存此列表,因为调用sitemaprolve
事件的频率可能比您预期的要高。特别是对于数据库类型SiteMapProvider
s
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;
}
我有一个类似的问题,就是在站点地图中使用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)));
}
没错,这适用于带有查询字符串的两个页面,但它似乎不是很灵活,因为您必须手动使用查询字符串对每个页面进行编码。没错,但如果您希望Web.sitemap更具动态性,您也可以使用Web.sitemap来标记此类URL。我将用一个例子更新帖子。获取此错误
名称“x”在当前上下文中不存在…
此处QueryStringField=x.Node[“QueryStringField”]
@BrijeshGandhi:oops;应该是节点[“queryStringField”]
。固定的。
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)));
}