ASP.NET - HttpContext.Current is null in EndXXX method of asynchronous web methods pair

Well, I am in a bit of a hurry, so if you are not aware of what asynchronous web-methods in ASP.NET web-services are, or why and how to use them, check out this article on MSDN.

Essentially, you split your regular web-method (let's say XXX) to a pair of web-methods (BeginXXX and EndXXX) with particular signatures, enabling them to run in background freeing-up the ASP.NET thread pool thread for handling requests. This is only useful if your web-method is expected to perform a long-running task.

I was just stumped by a particular aspect of this pair of asynchronous web-methods. I had delivered perfectly running web-service code to a client yesterday, and it was going through a staging server for final clearance, when I was reported that my web-service was failing with a NullReferenceException.

Stumped, I verified the entire code on my dev machine, and could not figure out anything and the code was running exactly as it should. However, I was able to reproduce the issue on the staging server. The lack of debugging tools on the staging server crippled my ability to figure out something quickly. Back to the old dark days of non-systematic debugging, I recompiled the code in debug mode, and moved it to the staging server, which helped me figure out the exact line number and file which generated the exception, which was the 7th line in the following code (accessing HttpContext.Current):

 

{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }if (ConfigurationManager.AppSettings["dbname"] != null) { return ConfigurationManager.AppSettings["dbname"]; } else { return Convert.ToString(HttpContext.Current.Session["s_dbname"]).ToUpper(); } {/syntaxhighlighter}

This code was being executed from the EndXXX method of the asynchronous web-methods pair in a deeply nested call hierarchy. Because of the difference in configuration in web.config, this line was invoked on the staging server, but not on my machine.

Placing a sequence of checks for null references then pin-pointed the issue with HttpContext.Current being null, and then I was able to figure out that HttpContext.Current always returns null, when accessed from the EndXXX method of an asynchronous pair of web-methods.

The remedy was pretty simple, add the following as the first line to the EndXXX method:

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }[WebMethod(EnableSession=true)] public void EndXXX(IAsyncResult result) { HttpContext.Current = this.Context; }{/syntaxhighlighter}

You are simply assigning the HttpContext.Current back available through the this reference (pointing to your web-service object).

Phew, a couple of hours of wasted productivity. I quickly checked it with asynchronous web pages, the HttpContext.Current is null in the End method of the asynchronous page too.

 

 

Comments

Than you for the post; saved me couple of hours of debugging :)

Thank you very much! I would never have thought you could assign to HttpContext.Current.

Champagne!  ;-)

rahul's picture

Well this (assigning to HttpContext.Current) is a very well known and commonly used technique for various purposes; e.g. for background processes in ASP.NET applications that invoke code (e.g. in Controllers) needing presence of HttpContext, the background process would normally create a custom context and assign it before invoking the other code requiring a context. Creating a custom context and setting it as current is as simple as this:

{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }SimpleWorkerRequest request = new SimpleWorkerRequest("dummy.html", null, new StringWriter()); current = new HttpContext(request); current.Items["ConfigCustomContext"] = true; HttpContext.Current = current;{/syntaxhighlighter}