Tag Archives: asp.net

Unable to start debugging on the web server

If you’re getting this error when trying to debug an ASP.NET Web application on IIS7 or greater, check the system.webServer element in your Web.config.  If you have the httpErrors element configured, you won’t be able to debug.  For your local dev environment, remove or comment out the httpErrors element, and you should be good to go.

<WAG>
From my ASP.NET 1.1 days, I have a hazy memory of Visual Studio’s debugging startup process requesting a bogus URL on the target Web site, and then doing something with the 404 response prior to launching the debugging session.  Obviously, if it’s expecting a 404 or the page to contain certain text, redirecting to an error page will prevent you from launching the debugger successfully.
</WAG>

If you happen to know specifically why this happens, please leave a comment (or contact me if comments are closed), and I will gladly update this entry.

"HTTP Error 401.1 – Unauthorized" when using Windows Authentication on IIS7.5

You may have run into this error while trying to develop a site that uses Integrated Windows Authentication on Windows Server 2008 R2 with IIS7.5.  I sure did, and I beat my head against the wall for a couple of hours trying to figure it out.

It turns out to be a security mechanism built into Windows, and the workaround is simple.  Just choose one of the two methods listed in this Microsoft KB article:

You can find a more detailed explanation here:

Hope this saves you some time.

(h/t to this ServerFault.com question/answer: IE 8 Authentication Denied on local SharePoint Site)

Another code snippet of the day

Today’s a good day. Check this out:

private static Dictionary&lt;string, string&gt; _dict = new Dictionary&lt;string, string&gt;();

static MyPage()
{
    //_dict.Add(&quot;item1&quot;, &quot;val1&quot;);
    //_dict.Add(&quot;item2&quot;, &quot;val2&quot;);
    //_dict.Add(&quot;item3&quot;, &quot;val3&quot;);
    //_dict.Add(&quot;item4&quot;, &quot;val4&quot;);
}

private void InitDictionary()
{
    try
    {
        _dict.Add(&quot;item1&quot;, &quot;val1&quot;);
        _dict.Add(&quot;item2&quot;, &quot;val2&quot;);
        _dict.Add(&quot;item3&quot;, &quot;val3&quot;);
        _dict.Add(&quot;item4&quot;, &quot;val4&quot;);
    }//END TRY
    catch
    {
        _dict.Clear();
        _dict.Add(&quot;item1&quot;, &quot;val1&quot;);
        _dict.Add(&quot;item2&quot;, &quot;val2&quot;);
        _dict.Add(&quot;item3&quot;, &quot;val3&quot;);
        _dict.Add(&quot;item4&quot;, &quot;val4&quot;);
    }//END CATCH
}

So what happened here? The guy decided that initializing the static dictionary variable in the static constructor wasn’t good enough, and that he needed to do it on every page request, so he created an instance method to do the initialization. For some reason, though, he kept getting an exception when initializing the dictionary after the first page view. Hmm… bettter just swallow the exception, clear the dictionary, and try again.

*slaps forehead*

Code snippet of the day

Just ran across this awesomeness today:

string campaignId = null;

/* ------------------------------------------------------------------------
 * see if the campaign id is in the request query params, so that a default
 * based on the url can be set.
*/
foreach (object key in Request.Params)
{
    string objCampaign = Convert.ToString(key);
    if (string.Compare(objCampaign, &quot;campaignid&quot;, true) == 0)
    {
        campaignId = Request[Convert.ToString(objCampaign)];
        break;
    }//END IF
}//END FOREACH
/* ---------------------------------------------------------------------- */

Huh. Well, that’s one way to do a Request.QueryString["campaignid"] lookup.

Enumerating HttpModules

One common ASP.NET performance tip is to remove any HttpModules that your application does not use.  You can take a peek at which modules are loaded by the framework on your behalf by examining the framework's Web.config file, but how do you find out which modules are actually loaded in the current context?

Fortunately, the HttpApplication instance provides a Modules collection that you can loop through:

// Get a collection of modules loaded for the current context.
HttpModuleCollection modules = HttpContext.Current.ApplicationInstance.Modules;

// Enumerate the loaded HttpModules and do something with them.  For example, you can
//  create a table, listing each module by key and full type name.
// NOTE: the key is the same key specified in Web.config to add the module.
foreach (string moduleKey in modules.Keys)
{
    IHttpModule module = modules[moduleKey];

    // Do something with the module key and/or the HttpModule.
}

You can then use the Modules collection create a table like this:  

And boom, there you have it: a list of HttpModules that are loaded for the current context.  You can use this information to determine which HttpModules are needed by your application, and which ones you can safely remove.

HttpValueCollection.ToString() generates your nice query strings

In an ASP.NET page, if you call Request.QueryString.ToString(), you'll get a nicely formatted query string back, like this:

 my=query&string=value&foo=bar

"That's nice," I thought.  "I wonder how they implemented it.  I'll fire up Reflector and take a look."

However, when you look at the declaration of QueryString in HttpRequest, you'll see that it is of type NameValueCollection, a class that has no ToString() override; at first glance, it looks like you'd simply be calling System.Object.ToString().

Obviously, this is not what is happening, so to find out how the query string is being generated, I had to dig just a little bit deeper.  Fortunately, VS2008 lets you step into the framework.

When you step in you'll see that HttpRequest.QueryString is indeed defined to be of type NameValueCollection, but when it actually gets instantiated, it is initialized to be of type HttpValueCollection, an internal class that derives from NameValueCollection. 

HttpValueCollection has a ToString() override that does the dirty work of constructing the nice query string that you see at the top of this post.

I'm so glad that Microsoft decided to allow us to step into the framework source code.  Otherwise, I probably would have spent a good hour trying to track down the magical NameValueCollection.ToString() call.

Response.Redirect and the ThreadAbortException, and why it’s a good thing

A couple of months ago, I ran into a problem where I was seeing a bunch of ThreadAbortExceptions showing up in my logs.  It didn’t take long to track down why – I was calling Response.Redirect from within a try/catch block in my ASP.NET code-behind page, and the catch block was catching the ThreadAbortException and writing it out to the log.  But why was the ThreadAbortException being generated? 

It turns out that Response.Redirect, when called with just the URL, or with the URL and a Boolean value of true, calls the Response.End method.  Response.End then calls Thread.Abort on the current thread, and, assuming that the page is in a cancellable state, this method throws the ThreadAbortException, alerting the framework that it is time to stop this thread, and NOW.

Why is this a good thing?

Let’s step back a bit and look at the recommended workaround for dealing with the ThreadAbortException.  Googling for an answer yields many suggestions to call Response.Redirect and pass the Boolean value false as the second, optional parameter.  This effectively suppresses the ThreadAbortException, preventing it from being caught and potentially logged as an error.

All is well and good, right?  Isn’t this what we want?

Not quite.

One side-effect of suppressing the ThreadAbortException is that any code after Response.Redirect is still executed.  This includes any event handlers in the page lifecycle that have yet to execute.  This is a waste of system resources, particularly if any of these event handlers contains resource-intensive code.

For the sake of illustration, let’s assume that our page, Default.aspx, has event handlers for most of the Page’s events:

  • Page_PreInit
  • Page_Init
  • Page_InitComplete
  • Page_PreLoad
  • Page_Load
  • Page_LoadComplete
  • Page_PreRender
  • Page_PreRenderComplete
  • Page_SaveStateComplete

Let’s further assume that each of these event handlers contains a resource- and time-intensive operation.  It could be a database call, a network call, or a batch image manipulation.  Whatever it is, it requires a lot of resources and a lot of time.

Each event handler will append a string to a StringBuilder member variable called _EventsFired.  Immediately preceding the call to Response.Redirect, _EventsFired will be stored as a Session variable so that the error page, Error.aspx, can display which methods were called.  The Redirect will occur in the Page_Load method; the user will be sent from Default.aspx to Error.aspx, which will then display the contents of _EventsFired.

Here is the code listing of Default.aspx’s Page_Load event handler:

protected void Page_Load (Object sender, EventArgs e)
{
    _EventsFired.Append (&quot;Page_Load called.  Resource-intensive operation executed.&lt;br /&gt;&quot;);

    try
    {
        Session[&quot;ErrorMessage&quot;] = _EventsFired;

        Response.Redirect (&quot;Error.aspx&quot;, false);
        Context.ApplicationInstance.CompleteRequest ();
    }
    catch (Exception ex)
    {
        _EventsFired.Append (ex.ToString ());
    }
}

Notice how we are passing false as the second parameter of Response.Redirect, meaning that we will prevent a ThreadAbortException from being thrown. 

Here is the output from Error.aspx:

Page_PreInit called. Resource-intensive operation executed.
Page_Init called. Resource-intensive operation executed.
Page_InitComplete called. Resource-intensive operation executed.
Page_PreLoad called. Resource-intensive operation executed.
Page_Load called. Resource-intensive operation executed.
Page_LoadComplete called. Resource-intensive operation executed.
Page_PreRender called. Resource-intensive operation executed.
Page_PreRenderComplete called. Resource-intensive operation executed.
Page_SaveStateComplete called. Resource-intensive operation executed.
Render called.

Page execution did not stop at Page_Load, even though we told the Application to complete the request!  In all likelihood, this is not the desired behavior, especially if any of the post-Load event handlers contains time-consuming or resource-intensive operations.

Now let’s modify Default.aspx’s Page_Load event handler to call Response.Redirect without suppressing a ThreadAbortException from being thrown:

protected void Page_Load (Object sender, EventArgs e)
{
    _EventsFired.Append (&quot;Page_Load called.  Resource-intensive operation executed.&lt;br /&gt;&quot;);

    try
    {
        Session[&quot;ErrorMessage&quot;] = _EventsFired;

        Response.Redirect (&quot;Error.aspx&quot;);
    }
    catch (Exception ex)
    {
        _EventsFired.Append (ex.ToString ());
    }
}

Here is the output from Error.aspx (remember, this is the list of events that fired during the processing of Default.aspx):

Page_PreInit called. Resource-intensive operation executed.
Page_Init called. Resource-intensive operation executed.
Page_InitComplete called. Resource-intensive operation executed.
Page_PreLoad called. Resource-intensive operation executed.
Page_Load called. Resource-intensive operation executed.
System.Threading.ThreadAbortException: [snip] Default.aspx.cs:line 45

It’s almost what we want, but notice that we “logged” the ThreadAbortException.  We need a way to exclude that from being logged. 

Let’s modify Default.aspx’s Page_Load event handler one more time:

protected void Page_Load (Object sender, EventArgs e)
{
    _EventsFired.Append (&quot;Page_Load called.  Resource-intensive operation executed.&lt;br /&gt;&quot;);

    try
    {
        Session[&quot;ErrorMessage&quot;] = _EventsFired;

        Response.Redirect (&quot;Error.aspx&quot;);
    }
    catch (System.Threading.ThreadAbortException)
    {
        throw;
    }
    catch (Exception ex)
    {
        _EventsFired.Append (ex.ToString ());
    }
}

Here is the output from Error.aspx:

Page_PreInit called. Resource-intensive operation executed.
Page_Init called. Resource-intensive operation executed.
Page_InitComplete called. Resource-intensive operation executed.
Page_PreLoad called. Resource-intensive operation executed.
Page_Load called. Resource-intensive operation executed.

Success!  Finally, the desired result!

  • The page stopped processing when it was supposed to, right after the call to Response.Redirect.
  • Event handlers later on in the page lifecycle were not unnecessarily executed.
  • The ThreadAbortException was not “logged” by our catch block.  Instead, it was explicitly caught and rethrown up the stack.

So there we have it.  Suppressing the Response.Redirect-generated ThreadAbortException can be a bad thing, particularly if there is a lot of resource-intensive code left to execute after the redirect.  To prevent those pesky ThreadAbortExceptions from showing up in our log files, all we have to do is explicitly catch them and rethrow them.  On busy sites, this can help to conserve scarce resources.

Used properly, ThreadAbortException is your friend.

Update 2007-08-01 07:44

Of course, I could have moved the Response.Redirect outside of the try/catch.  However, the code that prompted the writing of this article is legacy production code that can't be modified at my whim, hence the need for this approach.

Update 2008-04-05:  Moved over from jonsagara.com.