Posted at: 12:18 PM on 19 August 2009 by Muhimbi
At Muhimbi we take great pride in the fact that we actually deal with exceptions properly. And when I say properly I mean Not ignoring them, not letting them bubble to the top and make it the users’ problem, but rather catch them, enrich them, log them, take appropriate action and present the user with a friendly message. Oh… and LOG THEM! See, it is so important I mentioned it twice.
During a recent test cycle of our SharePoint Audit Suite, we noticed the following entry in the Event log. The weird thing is that it only happens if the particular Application page was the first page being requested since the Application Pool was last recycled, and only if that request was made by a non privileged (read not a development I can go anywhere administrator) account.
* Message: The file _app_bin/layouts.sitemap required by XmlSiteMapProvider does not exist.
- Exception: System.InvalidOperationException
- StackTrace: at System.Web.XmlSiteMapProvider.CheckSiteMapFileExists()
at Muhimbi.SharePoint.Audit.AuditLogViewer.provider_SiteMapResolve(Object sender, SiteMapResolveEventArgs e)
Fortunately, and surprisingly, the error message is quite descriptive. Our first hunch was that SharePoint is trying to load ‘_app_bin/layouts.sitemap’ using the current user’s credentials. After the first request is successful it caches the file for future requests, quite sensible.
To prove our hypothesis we fired up our favourite troubleshooting tool, Process Monitor (Thanks Mark!) and placed a filter on the file system to only return entries containing ‘.sitemap’. After making the first request it became clear that SharePoint is indeed using the current user’s account to access this file as is evident in the following screenshot.
The solution, as it so often is, is to elevate the part of the code that causes the sitemap file to be read. in our case the following bit.
/// Event handler that allows the breadcrumb to be modified.
public SiteMapNode provider_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
// ** Irrelevant code removed for the sake of clarity
// ** First request uses the current user's account to load sitemap file, so elevate.
SiteMapNode listNode = e.Provider.RootNode.ChildNodes.Clone();
listNode.Url = url;
listNode.Title = title;
listNode.ChildNodes = new SiteMapNodeCollection();
pageTitleNode = new SiteMapNode(e.Provider, Guid.NewGuid().ToString());
pageTitleNode.Title = HttpContext.GetGlobalResourceObject("MuhimbiAuditSharedResources", "Page_Title_AuditLogViewer").ToString();
pageTitleNode.ParentNode = listNode;
catch (Exception ex)
Another case…err…bug closed, download our full and free SharePoint Development Guidelines.