What’s wrong with ASP.NET provider model? – The XmlSiteMapProvider

Besides the problem with spaces in query strings (the same thing happens for the entire URL), you cannot subclass the XmlSiteMapProvider and use it if your site has site map definitions in files placed in each folder of the site instead of the a single one in the root of the site.

Suppose you want to build a site map provider that works like the XmlSiteMapProvider but the security trimming is based solely on the user's roles and not taking into account URL or File authorization.

The way security trimming is supposed to work with the XmlSiteMapProvider doesn't allow you to do this because it will show in the site map all resources accessible to the user independently of the roles declared in the site map definition.

(Before someone starts to complain about security issues, let me remember you that I can have my own authorization module that won't allow access to resources that aren't in the site map)

Such a site map provider can easily be developed. It can be something like this:

public class MyXmlSiteMapProvider : System.Web.XmlSiteMapProvider

{

    public override bool IsAccessibleToUser(System.Web.HttpContext context, System.Web.SiteMapNode node)

    {

        if (node == null)

        {

            throw new System.ArgumentNullException("node");

        }

        if (context == null)

        {

            throw new System.ArgumentNullException("context");

        }

        if (!this.SecurityTrimmingEnabled)

        {

            return true;

        }

 

        System.Collections.IList roles = node.Roles;

        System.Security.Principal.IPrincipal user = context.User;

        if (user == null || roles == null || roles.Count == 0)

        {

            return true;

        }

 

        foreach (string role in roles)

        {

            if ((role == "*") || user.IsInRole(role))

            {

                return true;

            }

        }

        return false;

    }

}

Now, suppose your site has some sub-folders (Customers, Suppliers, Admin) and you want to define the site map structure for each sub-folder in each sub-folder. Something like this:

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="~/Default.aspx" title="Home" description="Home Page" roles="*">

    <siteMapNode siteMapFile="~/Customers/Web.sitemap" />

    <siteMapNode siteMapFile="~/Suppliers/Web.sitemap" />

    <siteMapNode siteMapFile="~/Admin/Web.sitemap" />

  </siteMapNode>

</siteMap>

Well, if you are sub-classing the XmlSiteMapProvider, you can't. You'll have to fully develop your own XML site map provider. You don't have to type it yourself [^], but you'll have to maintain it.

It could be avoided if the XmlSiteMapProvider had been built with extensibility in mind (like the DataTable, for example) by adding a BuildNewXmlSiteMapProvider virtual method responsible for creating new XmlSiteMapProvider instances. This way, your provider could create its own new instances.

If you would like to see this implemented in ASP.NET, vote on my suggestion.

You can workaround this by adding a site map provider for each sub-folder:

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="~/Default.aspx" title="Home" description="Home Page" roles="*">

    <siteMapNode provider="CustomersSiteMap" />

    <siteMapNode provider="SuppliersSiteMap" />

    <siteMapNode provider="AdminSiteMap" />

  </siteMapNode>

</siteMap>

One Response to What’s wrong with ASP.NET provider model? – The XmlSiteMapProvider

  • Josh says:

    I think you are suppose to override a few methods like GetChildNodes etc…