在页面上添加一个SiteMapDataSource, SiteMapDataSource会使用web.config中指定的default siteMap provider读取web.sitemap的内容.
再把SiteMapDataSource作为数据源指定给Menu控件就搞定了.整个过程不用写一行代码
ASP.NET还提供了对权限控制和Localization的支持,
在web.config中设定sitemap provider是否对siteMapNode进行过滤:
<siteMap defaultProvider="SecuritySiteMap" enabled="true">
<providers>
<add name="SecuritySiteMap" type="System.Web.XmlSiteMapProvider, System.Web"securityTrimmingEnabled="true" siteMapFile="Web.sitemap"/>
</providers>
</siteMap>
securityTrimmingEnabled="true"说明对siteMapNode进行过滤
再在web.sitemap中对siteMapNode, Localization和权限进行设定:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap enableLocalization="true">
<siteMapNode url="~/default.aspx" title="$Resources: SiteMap, default" roles="admins"securityTrimmingEnabled="true">
<siteMapNode url="~/admin/user.aspx" title="$Resources: SiteMap, user" roles="admins" securityTrimmingEnabled="ture"/>
</siteMapNode>
</siteMap>
注意别忘记了enableLocalization="true",否则将什么也不显示,也不会报错
title="$Resources: SiteMap, default" 从global resource文件 SiteMap.resx中读取资源"default".
roles="admins" 说明此节点只对admins可见
BlogEngine 提供了自己的Menu和web.sitemap机制, 支持权限控制和Localization
具体实现见admin\menu.ascx
1.在web.sitemap中设置节点对应的角色:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<siteMapNode url="default.aspx" title="Blog Engine" description="" roles="administrators, editors">
<siteMapNode url="~/admin/Pages/Add_entry.aspx" title="add_entry" description="" roles="administrators, editors"/>
<siteMapNode url="~/admin/Pages/Blogroll.aspx" title="blogroll" description="" roles="administrators, editors"/>
<siteMapNode url="~/admin/Extension Manager/Default.aspx" title="Extensions" description="" roles="administrators"/>
</siteMapNode>
</siteMap>
注意title指定的是global资源名.
2. 使用两套PageSiteMap, 一个用于匿名用户.一个用于已登录用户(赞!)
<siteMap defaultProvider="PageSiteMap" enabled="true">
<providers>
<add name="PageSiteMap" type="BlogEngine.Core.Web.Controls.PageSiteMap, BlogEngine.Core"/>
<add name="SecuritySiteMap" type="System.Web.XmlSiteMapProvidersecurityTrimmingEnabled="true" siteMapFile="Web.sitemap"/>
</providers>
</siteMap>
PageSiteMap并没有从xml文件中读取设置.而是动态生成SiteMapNode(赞!)
SecuritySiteMap从xml文件中读取内容,securityTrimmingEnabled=true表明根据权限过滤节点
3. Build menu
用user control (admin\menu.ascx)来显示web.sitemap中的设定
private void BindMenu()
{
SiteMapNode root = SiteMap.Providers["SecuritySiteMap"].RootNode;
if (root != null)
{
foreach (SiteMapNode adminNode in root.ChildNodes)
{
if (adminNode.IsAccessibleToUser(HttpContext.Current))
{
if (!Request.RawUrl.ToUpperInvariant().Contains("/ADMIN/") && (adminNode.Url.Contains("xmanager") || adminNode.Url.Contains("PingServices")))
continue;
HtmlAnchor a = new HtmlAnchor();
a.HRef = adminNode.Url;
a.InnerHtml = "<span>" + Translate(adminNode.Title) + "</span>";//"<span>" + Translate(info.Name.Replace(".aspx", string.Empty)) + "</span>";
if (Request.RawUrl.EndsWith(adminNode.Url, StringComparison.OrdinalIgnoreCase))
a.Attributes["class"] = "current";
HtmlGenericControl li = new HtmlGenericControl("li");
li.Controls.Add(a);
ulMenu.Controls.Add(li);
}
}
}
}
注意web.sitemap中节点的Title只是字符串资源的名称.显示时会根据当前Culture抓取相应的资源
Web.SitMap 是 VS2005中一个非常重要的特性. 可以用于菜单等应用,但企业的应用中经常需要控制到 菜单的 target ,菜单的权限等.
通过扩展一些自定义属性可以实现(此方法已经在E8.Net 2.0 工作流应用架构中实现)
sitmap 范例:
可以看到 这个sitmap中 有 target diseable resourcekey ...等扩展属性 来实现菜单权限控制 及控制方式等
实现代码:
依据同样的方法,可以扩展更多的自定义属性,达到对sitMap 非常丰富的控制和展示逻辑.
E8.Net 工作流 开源架构 提供了全部实现的源码, 2.0下所有应用系统菜单(OUTLOOK风格),实现来自 web.sitMap