Determining a SiteMapNode's visibility at runtime
Just a random thought. Wouldn’t it be nice if the XmlSiteMapProvider or SiteMapDataSource had a CheckAccessibility event? All we would have to do is handle this event and set a property that determines if the node should be displayed or not.
This way, we can control a nodes visibility using some custom rules rather than role based visibility.
The provider would look like this
public class SecurityXmlSiteMapProvider : XmlSiteMapProvider {
public delegate void AccessibilityHandler(object sender, NodeAccessibleEventArgs e);
public event AccessibilityHandler CheckAccessiblity;
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node) {
NodeAccessibleEventArgs nodeAccEvtArgs = new NodeAccessibleEventArgs(node);
if (CheckAccessiblity != null) {
CheckAccessiblity(this, nodeAccEvtArgs);
return nodeAccEvtArgs.IsAccessible;
}
else {
return true;
}
}
}
The web.config file would contain this
<siteMap defaultProvider="SecurityXmlSiteMapProvider" enabled="true">
<providers>
<add
name="SecurityXmlSiteMapProvider"
description="Default SiteMap provider."
type="TestControls.SecurityXmlSiteMapProvider"
siteMapFile="Web.sitemap"
securityTrimmingEnabled="true"
/>
</providers>
</siteMap>
And at runtime, you would handle the event like so and determine if the node should be displayed or not (Could be simpler if we were handling the event in SiteMapDataSource).
protected void Page_Load(object sender, EventArgs e) {
SecurityXmlSiteMapProvider siteMapProvider = SiteMapDataSource1.Provider as SecurityXmlSiteMapProvider;
if (siteMapProvider != null) {
siteMapProvider.CheckAccessiblity += new SecurityXmlSiteMapProvider.AccessibilityHandler(siteMapProvider_CheckAccessiblity);
}
}
void siteMapProvider_CheckAccessiblity(object sender, NodeAccessibleEventArgs e) {
if (..Test Condition..) {
e.IsAccessible = false;
}
else {
e.IsAccessible = true;
}
}