Determining a SiteMapNode's visibility at runtime - Raj Kaimal

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;

    }

}

Published Friday, January 20, 2006 10:20 PM by rajbk
Filed under:

Comments

# re: Determining a SiteMapNode's visibility at runtime

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

Friday, January 20, 2006 11:41 PM by Chris Martin

# re: Determining a SiteMapNode's visibility at runtime

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

Stinky...

Friday, January 20, 2006 11:44 PM by Chris Martin

# re: Determining a SiteMapNode's visibility at runtime

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.

Monday, January 23, 2006 9:55 AM by a

# re: Determining a SiteMapNode's visibility at runtime

I think you would be better off using the roles attribute on the siteMapNode.  You could just set this to a role that doesn't exist.

Michael

P.S Code doesn't stink... if it does I'd be worried about what you're writting in.

Friday, October 06, 2006 1:21 PM by Michael

# re: Determining a SiteMapNode's visibility at runtime

NodeAccessibleEventArgs where can i find this?

Thursday, May 24, 2007 11:12 AM by Expectra

# re: Determining a SiteMapNode's visibility at runtime

I think, there are some good parts in what you described above.

I wouldn't probably use EventHandler<>, but I would try to use a delegate which takes a node or nodeID as a single parameter and returns a boolean value (Predicate<SiteMapNode> msdn.microsoft.com/.../bfcke1bz.aspx). So, it's basically what was called a callback in Windows.

This would allow your custom site map provider to delegate the responsibility of determining node visibility to some other subsystem of your application. So, you decoupled Site map provider class from "visibility provider" class and could possible use the same Site map provider with different "visibility providers".

In my application such "visibility provider" is called Roles and Rights Management System (RRM) and is based on three SQL tables: tRole, tRight, and tRightOfRole (many-to-many relationships). This is much more flexible and powerful than Windows Roles.

Note, that it has nothing to do with Page_Load event. You'd better specify your site map provider in web.config and initialize it on application startup by assigning Predicate<SiteMapNode> delegate to an appropriate method of "visibility provider".

Monday, June 02, 2008 12:56 AM by Vladimir Kelman

# re: Determining a SiteMapNode's visibility at runtime

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 (fredrik.nsquared2.com/viewpost.aspx)

Monday, June 02, 2008 1:06 AM by vkelman

Leave a Comment

(required) 
(required) 
(optional)
(required)