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;

    }

}

6 Comments

  • Sorry man. But that just reeks of code smell. It follows no guidelines of all other code in the framework and really is not intuitive at all.



    CheckAccessibility is not an event. It's a method.



    You would be better off creating your provider and adding a check where you want it. It'd be a lot simpler and clearer.



    Just my .02 cents

  • And you're actually changing an *EventArgs class on the client?



    Stinky...

  • Maybe my nose is stopped up, but I don't smell it. Doesn't this follow a similar pattern to the CancelEventArgs built into the framework? Handle some event, event handler has ability to Cancel the event from triggering future steps by changing e.Cancel in the event handler. Smells the same to me.



    How is this different.

  • I think you would be better off using the roles attribute on the siteMapNode. &nbsp;You could just set this to a role that doesn&#39;t exist.
    Michael
    P.S Code doesn&#39;t stink... if it does I&#39;d be worried about what you&#39;re writting in.

  • NodeAccessibleEventArgs where can i find this?

  • You could also use
    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection attributes)
    method of your CustomSiteMapProvider class to get a name of VisibilityProvider class and its method for assigning to CustomSiteMapProvider's delegate (http://fredrik.nsquared2.com/viewpost.aspx?PostID=272&showfeedback=true)

Comments have been disabled for this content.