SiteMap行为

时间:2009-03-10 14:42:16

标签: asp.net sitemap

我已经仔细研究了大量的MS文档,只是为了找到树状视图,就像使用站点地图一样。我不认为任何人都知道如何为站点地图导航建立类似文件夹的结构?例如,结构如下

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

“关于”和“联系人”将是文件夹,但站点地图永远不会在单个页面上分层。所以,我的根页面上有两个菜单项,一个是“Home”,它就像一个文件夹,可以深入到about和contact菜单,另一个是免责声明页面的链接。我希望能够点击Home,它将重新加载带有“About”和“Contact”链接的菜单,并完全隐藏“Home”和“Disclaimer”。

Home >
Disclaimer

然后点击主页,你会得到

About >
Contact >

然后点击关于你得到

Me
My Family
My Pets

每个菜单都有一个“向上”菜单,可以退回文件夹。

我看不到有一个简单的解决方案,但目前我们在整个Web应用程序中使用不同文件夹中的静态html页面。这是你需要改变的东西。

有什么想法吗?

修改

我不得不想出一个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>

这是直接在母版页文件中(临时的,我稍后会把它放在模型后面的代码中)。

然后我在身体中得到了这个

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

以下是示例站点地图。

2 个答案:

答案 0 :(得分: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(parent.ChildNodes中的SiteMapNode)

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

因此,我们调用每个页面加载的主要调用是这样的:

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

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

答案 1 :(得分:1)

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

所以,除了

之外,我的想法是做同样的事情
<ul>
   <li>
      <ul>
         <li></li>
      </ul>
   </li>
   <li></li>
   <li></li>
</ul>
而不是结构。根节点必须有一个runat =“server”,这样你可以遍历所有的子元素?这样我就可以在<li></li>元素中放置任何内容。

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