【问题标题】:SiteMap Behaviour站点地图行为
【发布时间】:2009-03-10 14:42:15
【问题描述】:

我仔细阅读了大量的 MS 文档,却发现使用站点地图的结构类似于树状视图。我想没有人知道如何为站点地图导航提供类似文件夹的结构?以如下结构为例

Home
   About
      Me.aspx
      MyFamily.aspx
      MyPets.aspx
   Contact
      Telephone.aspx
      Email.aspx
 Disclaimer.aspx

“关于”和“联系方式”将是文件夹,但站点地图绝不会在单个页面上分层。所以,我的根页面有两个菜单项,一个是“主页”,它就像一个文件夹,可以深入了解关于和联系人菜单,另一个是免责声明页面的链接。我希望能够单击主页,这将重新加载包含“关于”和“联系”链接的菜单,并完全隐藏“主页”和“免责声明”。

Home >
Disclaimer

然后点击主页,你会得到

About >
Contact >

然后当点击关于你会得到

Me
My Family
My Pets

每个菜单都会有一个“向上”菜单来返回一个文件夹。

我看不出有一个简单的解决方案,但目前我们使用静态 html 页面,这些页面位于我们的 Web 应用程序的不同文件夹中。正如您所想象的那样,这是需要改变的。

有什么想法吗?

编辑

我不得不想出一个 VB.NET 解决方案

<script runat="server">
  Private Function GetSecondaryNavItems() As String
    Dim sRet As String = ""

    Dim oCurrNode As System.Web.SiteMapNode = Nothing
    Dim oCurrParentNode As System.Web.SiteMapNode = Nothing

    'Dim sCurrPage As String = GetURL(Request.ServerVariables("SCRIPT_NAME").ToLower())
    Dim sCurrPage As String = GetURL(HttpContext.Current.Request.ServerVariables("SCRIPT_NAME").ToLower())
    oCurrNode = GetCurrentNode(sCurrPage, SiteMap.RootNode)

    If Not oCurrNode Is Nothing Then
      oCurrParentNode = oCurrNode.ParentNode
    End If

    If Not oCurrParentNode Is Nothing Then
      If Not oCurrParentNode Is SiteMap.RootNode Then
        sRet += "Parent Folder Link"

        If Not oCurrNode Is Nothing Then
          For Each oChild As SiteMapNode In oCurrParentNode.ChildNodes
            sRet += "Link for child"
          Next
        End If
      End If
    End If

    Return sRet
  End Function

  Private Function GetURL(ByVal fullURL As String) As String
    Return fullURL.Substring(fullURL.LastIndexOf("/"))
  End Function

  Private Function GetCurrentNode(ByVal _sCurrentPageURL As String, ByVal _oNode As SiteMapNode) As SiteMapNode
    Dim oNodeRet As SiteMapNode = Nothing

    For Each oNodeCheck As SiteMapNode In _oNode.ChildNodes
      If oNodeCheck.HasChildNodes = True Then
        oNodeRet = GetCurrentNode(_sCurrentPageURL, oNodeCheck)
      End If

      If oNodeRet Is Nothing Then
        Exit For
      End If

      Dim sURL As String = oNodeCheck.Url.ToLower()
      Dim iPos As Integer = sURL.IndexOf("?")

      If iPos > 0 Then
        sURL = sURL.Substring(0, iPos)
      End If

      iPos = sURL.LastIndexOf("/")

      If iPos > 0 Then
        sURL = sURL.Substring(iPos)
      End If

      If sURL = _sCurrentPageURL Then
        oNodeRet = oNodeCheck
        Exit For
      End If
    Next

    Return oNodeRet
  End Function
</script>

这个是直接在母版页文件中的(临时的,后面我会放在model后面的代码中)。

然后我在体内得到了这个

<div id="sidebar">
  <%= GetSecondaryNavItems() %>
</div>

再次,暂时只是为了测试。它实际上并没有输出任何东西,但是我认为我的 GetURL 定义不正确。我假设它只是获取实际文件?不过我可能错了:)

编辑编辑:由于某种原因,我没有得到任何输出,所以我认为这是我的站点地图。我需要调试它,但我现在正在远程处理,所以它很慢;)

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode url="Accounts/Default.aspx" title="Accounts"  description="Accounts">
    <siteMapNode url="Accounts/Test.aspx" title="Client Balances" description="Client Balances">
      <siteMapNode url="Hello.aspx" title="Hello"  description="rarar" />
      <siteMapNode url="Hiya.aspx" title="Hiya"  description="rarar" />
    </siteMapNode>
    <siteMapNode url="Test.aspx" title="Test"  description="rarar" />
  </siteMapNode>
</siteMap>

这是示例站点地图。

【问题讨论】:

    标签: asp.net sitemap


    【解决方案1】:

    您仍然可以使用 Sitemap.sitemap 文件来控制您的导航,但您不会使用 asp.net 中的任何内置控件来实现此目的。我刚刚在一个刚刚完成的网站上做了差不多的事情。

    让您的所有页面都继承自一个基页面类(或使用母版页,无论哪种方式,您都只会拥有一份代码副本。)

    在每个页面上创建一个 div 或 span,并命名为适当的名称(divNav 或 spnNav 或其他)。

    在您的基本页面中,在页面加载时,遍历所有站点地图节点以查找当前页面的节点。这需要是一个递归调用。

        // Pass the current page url, all the way through the .aspx.  In other words, do NOT pass any kind of 
        // query string.
        private SiteMapNode GetCurrentNode(string _sCurrentPageURL, SiteMapNode _oNode)
        {
            SiteMapNode oNodeRet = null;
    
            foreach (SiteMapNode oNodeCheck in _oNode.ChildNodes)
            {
                if (oNodeCheck.HasChildNodes == true)
                {
                    oNodeRet = GetCurrentNode(_sCurrentPageURL, oNodeCheck);
                }
    
                if (oNodeRet != null)
                    break;
    
                string sUrl = oNodeCheck.Url.ToLower();
                int iPos = sUrl.IndexOf("?");
                if (iPos > 0)
                    sUrl = sUrl.Substring(0, iPos);
                iPos = sUrl.LastIndexOf("/");
                if (iPos > 0)
                    sUrl = sUrl.Substring(iPos);
    
                if (sUrl == _sCurrentPageURL)
                {
                    oNodeRet = oNodeCheck;
                    break;
                }
            }
            return oNodeRet;
        }
    

    获得当前节点后,获取其父节点。

    添加一个链接(您称之为“返回文件夹的向上菜单”)。

    然后做一个foreach(SiteMapNode in parent.ChildNodes)

    为每个孩子添加一个链接。

    所以,我们在每次页面加载时调用的主调用是这样的:

        public string GetSecondaryNavItems()
        {
            string sRet = "";
    
            // Get the node that matches most of this url...
            System.Web.SiteMapNode oCurrNode = null;
            System.Web.SiteMapNode oCurrParentNode = null;
    
            string sCurrPage = GetURL(Request.ServerVariables["SCRIPT_NAME"].ToLower());
    
            oCurrNode = GetCurrentNode(sCurrPage, SiteMap.RootNode);
    
            if(oCurrNode != null)
                oCurrParentNode = oCurrNode.ParentNode;
    
            if(oCurrParentNode != null)
                  if(oCurrParentNode != SiteMap.RootNode)
                      sRet += "Parent Folder link";
    
                if(oCurrNode != null)
                {
                foreach (System.Web.SiteMapNode oChild in oCurrParentNode.ChildNodes)
                {
                        sRet += "Link for child";
                  }
            }
        }
    

    我必须告诉你,上面的代码部分是我复制的,部分是我写的。但这应该会给你一个好的开始,我想。

    编辑:很抱歉!这是 GetURL 过程...

        public string GetURL(string _sURL)
        {
            string sRet = _sURL;
    
            int iPos = sRet.IndexOf("?");
            if (iPos > 0)
                sRet = sRet.Substring(0, iPos);
            iPos = sRet.LastIndexOf("/");
            if (iPos > 0)
                sRet = sRet.Substring(iPos);
    
            return sRet;
        }
    

    【讨论】:

    • 如果您有空时检查我的编辑,那就太好了。干杯
    • 我刚刚在 C# 中为您添加了 GetURL,但您所拥有的可能应该有效,因为我敢打赌您没有在这些页面上使用查询字符串。我再看看。
    • 我似乎找不到它的问题,但没有任何输出,尽管它可能与我的站点地图有关(我已将它放在我的帖子的编辑中)。不幸的是,我明天再次上班时必须检查。为 sn-p 干杯,这很有意义。
    • 嘿 Kezzer -- 我明天会看看这个,但我怀疑问题可能是您在 Accounts 文件夹下有几个 URL。我不确定我的代码是否说明了这一点。明天我会使用你的站点地图,看看我能找到什么。
    • 它实际上是一个测试站点地图,如果站点地图存在逻辑错误,请大声告诉我。我们的站点地图非常大,最大深度可能为 5 或 6。干杯
    【解决方案2】:

    虽然我不应该回答,但实际上我会对此提出进一步的要求。是否可以使用仅由 &lt;ul&gt;&lt;li&gt; 元素组成的页面来做完全相同的事情?我问的原因是因为我们的“站点地图”实际上在安全性和功能方面都更先进一些。我们运行的菜单实际上有带有输入框的动态下拉列表,这是在站点地图中无法复制的。

    所以,我们的想法是做完全相同的事情,除了 a

    <ul>
       <li>
          <ul>
             <li></li>
          </ul>
       </li>
       <li></li>
       <li></li>
    </ul>
    

    结构。根节点上必须有一个 runat="server" ,这样您也许可以遍历所有子元素?这样我就可以在 &lt;li&gt;&lt;/li&gt; 元素中放置任何东西。

    我们的安全性也很零星,站点地图也没有我们正在寻找的那种精细控制。

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2010-09-05
      • 1970-01-01
      • 2013-12-23
      相关资源
      最近更新 更多