SiteMap网站地图在网站建设的时候是很有用的它可以直接绑定在Men和TreeView控件上还有一个指示当前路径的SiteMapPath控件也可以直接绑定
这是他常用的xml定义<siteMapNode url=Course/Group/GroupListaspx title=GroupAdmin >这个SiteMap的权限已经和Membership结合起来了不同权限的用户所看到的地图已经被控制了可以配置role属性来扩展例外的访问许可注意是例外的访问许可
<siteMapNode url=Course/Tests/TestListaspx title=TestAdmin role=student>这里有些介绍
简单的使用这里不作赘述只是讨论一下怎么和扩展一下让他可以访问资源时附带参数
首先介绍这样一个资源MySiteMapTool这位仁兄已经提供了一个工具可以在程序中转发带参数的请求比如 MySiteMapForward(Details AlbumID={}&Page={} )确是简单实用
现在想要的功能是因为各个液面都需要不同的参数所以在没有这些参数的情况下就禁止用户访问那个页面转而访问父一级页面递归
首先SiteMap本身有个SiteMapResolve事件在当前路径被解析时触发这是一段来自MSDN的代码
private void Page_Load(object sender EventArgs e)
{ // The ExpandForumPaths method is called to handle // the SiteMapResolve event SiteMapSiteMapResolve += new SiteMapResolveEventHandler(thisExpandForumPaths)}
private SiteMapNode ExpandForumPaths(Object sender SiteMapResolveEventArgs e)
{ // The current node represents a Post page in a bulletin board forum // Clone the current node and all of its relevant parents This // returns a site map node that a developer can then // walk modifying each nodeUrl property in turn // Since the cloned nodes are separate from the underlying // site navigation structure the fixups that are made do not // effect the overall site navigation structure SiteMapNode currentNode = SiteMapCurrentNodeClone(true)SiteMapNode tempNode = currentNode
// Obtain the recent IDs int forumGroupID = GetMostRecentForumGroupID()int forumID = GetMostRecentForumID(forumGroupID)int postID = GetMostRecentPostID(forumID)
// The current node and its parents can be modified to include // dynamic querystring information relevant to the currently // executing request if ( != postID)
{ tempNodeUrl = tempNodeUrl + ?PostID= + postIDToString()}
if ((null != (tempNode = tempNodeParentNode)) &&( != forumID))
{ tempNodeUrl = tempNodeUrl + ?ForumID= + forumIDToString()}
if ((null != (tempNode = tempNodeParentNode)) &&( != forumGroupID))
{ tempNodeUrl = tempNodeUrl + ?ForumGroupID= + forumGroupIDToString()}
return currentNode}
这段代码只是给当前路径加载参数
曾经尝试过使用类似的方法但是SiteMapPath搞定了Menu就绑定不上数据了并且只能处理一部分数据
后来结合SiteMapTool那个类又写出几个函数可以解决这个问题这是修改之后的sitemap文件加了一个配置项rule里面的参数是这个页面需要的参数如果当前上下文没有这些参数那么禁止用户访问这个页面
<siteMapNode url=Course/Group/GroupDetailaspx title=Group Detail rule=cidgid>这是两个函数递归处理所有的路径 private string MakeURL(SiteMapNode node)
{ nodeReadOnly = false//find the static url string url = MySiteMapFindForward(nodeTitle)if (node[rule] != null && node[rule]Length > )
{ //if have the rulethen check string[] paramSet = node[rule]Split()//check for (int i = i < paramSetLength i++)
{ //if request have not such a param then invoke self to check his parent if (HttpContextCurrentRequestParams[paramSet[i]] == null)
return MakeURL(nodeParentNode)} //if pass then add all the params and return the value url += ?for (int i = i < paramSetLength i++)
{ string key = paramSet[i]//cid——>cid= the former format is like rule=cidtid url = url + key + = + HttpContextCurrentRequestParams[key] + &} return urlSubstring( urlLength ) //remove last &
} else { //if there is no rule then return the url directly return url} } private void ReBindData(SiteMapNode root)
{ string url = MakeURL(root)if (url != )
rootUrl = urlfor (int i = i < rootChildNodesCount i++)
{ ReBindData(rootChildNodes[i])} }在ReBindData里面递归调用MakeUrl函数
MakeUrl函数里面调用的MySiteMapFindForward函数就是来自那位的实现
不过应用的是后需要做一些改动他原来的实现是用静态的类如此加载//SiteMapNodeCollection smc = SiteMapRootNodeGetAllNodes()//siteMapCol = new NameValueCollection()
//IEnumerator ie = smcGetEnumerator()//while (ieMoveNext())
//{ // siteMapCol[((SiteMapNode)ieCurrent)Title] = ((SiteMapNode)ieCurrent)Url//}但是由于用户在没有登陆的时候限于权限它能访问的页面有限所以SiteMapRootNodeGetAllNodes()得到的不是所有数据可能只是一部分或者改动方式就是自己写一个函数直接读取xml文件递归获取所有数据定义