网站地图导航和查询字符串 [英] SiteMap Navigation and Query String

查看:130
本文介绍了网站地图导航和查询字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我试图找出我怎么能动态查询字符串参数添加到我的网站地图导航菜单。例如,用户选择他想要一起工作的源和版本。我有一个简单的网站地图创建导航链接,但需要在查询字符串传递用户选择的参数。默认的地图看起来是这样的:

Currently I am trying to figure out how I can add dynamic query string parameters to my sitemap navigation menu. For example, the user chooses the source and edition he wants to work with. I have a simple sitemap that creates navigational links but the parameters the user chose need to be passed in the query string. The default map looks like this:

<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>

现在链接将需要有动态取决于什么由用户选择添加的参数。例如:

Now the links will need to have the parameters added dynamically depending on what was chosen by the user. For example:

<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" />

希望这是相当清楚的。让我知道,如果有人需要更深入的解释。

Hopefully this is fairly clear. Let me know if anyone needs deeper explanation.

感谢

推荐答案

不幸的是,这是默认不支持。但是你可以实现在 SiteMap.SiteMa preSOLVE 事件的的Global.asax 赶上这样的扩展的URL,并调用 SiteMapProvider.FindSiteMapNode 通过正确的网址:

Unfortunately, this is not supported by default. But you can implement the SiteMap.SiteMapResolve event in your Global.asax to catch such extended urls, and call SiteMapProvider.FindSiteMapNode with the correct url:

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,这适用于任何供应商。

No need for custom SiteMapProviders, this works with any provider.

现在,如果你想成为更有活力,你可以做几件事情,例如(有5路):

Now, if you want to be more dynamic, you can do several things, for example (there are may ways):

标记的所有&LT;&的SiteMapNode GT; 用一个特殊的属性部分的查询字符串匹配的标签,并通过遍历整个地图加载此清单。与该方法的问题是,这可以是用于某些网站地图提供者(基于文件的提供者是一个提供程序是用于这样的方法的良好匹配的一个例子)效率非常低。你会做的话,是这样说

Flag all <siteMapNode> tags with partial querystring matching with a special attribute, and load this list by iterating the entire sitemap. The problem with that approach is that this can be very inefficient for some sitemap providers (the file-based provider is an example of a provider that is a good match for such an approach). What you'd do then, is to say something like

<siteMapNode url="~/Image.aspx?location=Our Products"
             queryStringField="location"
             title="Our Products" description="Our Products" />

在code,你可以通过递归从根开始的节点,并以 queryStringField 属性记住所有节点找到这样的节点:

In code you could find such nodes recursively by starting at the root node, and remembering all nodes with a queryStringField attribute:

private IEnumerable<SiteMapNode> 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;
        }
    }
}

通过这个名单在手,有的挥手,你应该能够做同样的伎俩。请注意,你应该需要缓存此列表,因为 SITEMA preSOLVE 事件可往往比你所期望的调用。特别是对于数据库型 SiteMapProvider 秒。

With this list in hand, and some hand waving, you should be able to do the same trick. Note that you should probably need to cache this list, because the SiteMapResolve event can be called more often than you'd expect. Especially for database-type SiteMapProviders.

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;
}

这篇关于网站地图导航和查询字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆