KB: When is the SPContext.Current available ? (SharePoint dev)

We always assumed wherever you have an HTTP Context (i.e., wherever SPContext.Current is not null), that you could access the SharePoint context through SPContext.Current. This was the case with MOSS 2007 RTM and SP1, but this changed with the recent Infrastructure Update. The following update to when SPContext is supported has been confirmed by Microsoft PSS. (Props to Nishand for confirming this behavior change.)

Prior to the IHttpHandler.ProcessRequest method, the SharePoint application runtime is busy building an impersonation context of the calling user. This means that you CANNOT access SPContext.Current UNTIL the ProcessRequest method. This also means within the constructor of the handler OR from a factory pattern– regardless of whether it’s a Page or IHttpHandler endpoint. Note that this is a COMPLETE CHANGE OF BEHAVIOR (processing timeline) that the infrastructure update introduces.

Bottom line– this means that if you are implementing IHttpHandlerFactory instances, you cannot access the SPContext.Current object or anything deriving from there in the factory—you must wait until IHttpHandler.ProcessRequest. (NOTE: I haven’t tested this, but this also will affect HTTP modules).

The following code sample demonstrates the bug. The handler factory will fail every time, while the handler will work every time.

using System.Web;
using Microsoft.SharePoint;

namespace NGSupport{
    // Unsupported code: fails AFTER infrastructure update
    public class TestHandlerFactory : IHttpHandlerFactory{
        public IHttpHandler GetHandler(HttpContext context,
                    string requestType, string url, string pathTranslated) {
            // Breaks every time (after infrastructure update)
            // as WSS hasn’t loaded the impersonation context,
            // and the SharePoint context is NOT available
            var spContext = SPContext.Current;
            return new TestHandler();
        }
        public void ReleaseHandler(IHttpHandler handler) {}
    }

    // Supported code: works every time
    public class TestHandler : IHttpHandler{
        public bool IsReusable{get { return true; } }
        public void ProcessRequest(HttpContext context) {
            // Will work just fine– you can always access SPContext.Current in ProcessRequest
            var spContext = SPContext.Current;
            context.Response.Write(spContext.Web.Title.ToString());
        }
    }
}

To test this out, compile this into a DLL called "NGSupport" and register the following handlers in web.config (may require elevated or WSS_Medium trust):

<add verb="GET,HEAD" path="foo.test" type="NGSupport.TestHandlerFactory, NGSupport" validate="false" />
<add verb="GET,HEAD" path="bar.test" type="NGSupport.TestHandler, NGSupport" validate="false" />

You should see that foo.test will work before the infrastructure update but break after it’s applied, however you’ll see that bar.test will always work as that is the supported code path.

Props to the NewsGator dev, support and qa teams for identifying and resolving this issue quickly.

This entry was posted in SharePoint. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s