Chris Haas's Blog

October 21, 2009

Solving “The default script language specified for this application is invalid”

Filed under: Uncategorized — Tags: , , — chrishaas @ 3:38 pm

This was a pain in the butt. Like everyone else I tried registering things, unregistering things, deleting “MBSchema.bin.00000000h” and resetting permissions. None of that worked, or at least none of the entries people talked about. But maybe my problem was from running IIS on a 64-bit machine under 32-bit mode. So I fired up Process Monitor and watched for some ACCESS DENIED error messages. Right away I found w3wp.exe had a problem accessing HKCR\Wow6432Node\VBScript. I tried giving IUSR_MACHINE the Read permission but that didn’t seem to work. In the end I just decided to give Users and Everyone both Read access to that key. And voila, it worked.

This machine hadn’t been updated in a while and yesterday while connecting to Windows Update we were getting a 0×80070020 error message. After fixing that (a whole other story) we installed a bunch of patches but apparently didn’t notice that they took down our other sites. I’m guessing that somewhere in the middle of the night that the app pools recycled from inactivity because someone would have said something yesterday if they were down. Unfortunately I’m too lazy to go through my logs to figure out what was all applied yesterday so I can’t blame a specific patch and I don’t really care to, either.

After that problem we were getting 8002801d error messages from ASP. After monkeying around for a while I stumbled on a “Microsoft FixIt” tool for this problem and that solved everything. When did these “Microsoft FixIt” things come out? When they work, they’re awesome!

April 22, 2009

True ASP.Net (and IIS) 404 errors

Filed under: Uncategorized — Tags: , — chrishaas @ 9:26 pm

UPDATE: I should found out that in ASP.Net 3.5 the <customErrors> section in web.config now supports the attribute redirectMode which default to ResponseRedirect but can be changed to ResponseRewrite. This will force the proper HTTP status codes to come through for errors.

So I launched a new site porting it from static .html files to dynamic .aspx. I then created an entry for 404’s in web.config and also told IIS to send 404’s to the same page for everything that ASP.Net didn’t handle (images, html files, etc). So simple, right? Unfortunately both ASP.Net and IIS don’t appear to actually send a 404 status code for 404’s if you have a 404 handler specified. IIS actually sends a 200 OK and performs the equivalent of a Server.Transfer. ASP.Net actually sends a 302 Found which is a client-side redirect.

Now, you may not care about this, but if you’re trying to purge search engines of old content you should.

The fix, at first glance, is simple. In Page_Load on the 404 handler page just send the proper status code using Response.StatusCode = 404. This actually fixes the problem with IIS but we’ve still got an ASP.Net problem. ASP.Net will actually still send the 302 redirecting people to the 404 page and then send the 404 code. So if page Blah.aspx doesn’t exist you’ll get a 302 code saying to go to PageNotFound.aspx. When the browser requests PageNotFound.aspx they finally get the 404 response. Now maybe that’s good enough for you, but not for me. When I 404, I want to know right away, not after a redirect.

I found the solution here and have reproduced the code below for easy copy-and-paste. They don’t explicitly mention it in the article but you MUST set the <customErrors> to Off or at least RemoteOnly. I know that sounds weird but the code below still actually processes the <customErrors>, it just does it instead of letting ASP.Net handle it for you.

The article talks about creating a DLL but you can just as easily drop it into App_Code as a file named HttpErrorModule. Then just add <add name="HttpErrorModule" type="HttpErrorModule" /> to your <httpModules>.

One other thing to note, this module actually overrides all errors and sends their proper codes in the response stream. This shouldn’t cause any problems but you should be aware of it when debugging. You could very easily add some logic to check for 404’s only, too.

'Code from: http://www.colincochrane.com/post/2008/01/ASP-NET-Custom-Errors-Preventing-302-Redirects-To-Custom-Error-Pages.aspx
Option Strict On
Option Explicit On

Imports System.Web
Imports System.Web.Configuration

Public Class HttpErrorModule
    Implements IHttpModule

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
        'Nothing to dispose.
    End Sub
    Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
        AddHandler context.Error, New EventHandler(AddressOf Context_Error)
    End Sub

    Private Sub Context_Error(ByVal sender As Object, ByVal e As EventArgs)
        Dim context As HttpContext = CType(sender, HttpApplication).Context
        If (context.Error.GetType Is GetType(HttpException)) Then
            ' Get the Web application configuration.
            Dim configuration As System.Configuration.Configuration = WebConfigurationManager.OpenWebConfiguration("~/web.config")

            ' Get the section.
            Dim customErrorsSection As CustomErrorsSection = CType(configuration.GetSection("system.web/customErrors"), CustomErrorsSection)

            ' Get the collection
            Dim customErrorsCollection As CustomErrorCollection = customErrorsSection.Errors
            Dim statusCode As Integer = CType(context.Error, HttpException).GetHttpCode

            'Clears existing response headers and sets the desired ones.
            context.Response.ClearHeaders()
            context.Response.StatusCode = statusCode
            If (customErrorsCollection.Item(statusCode.ToString) IsNot Nothing) Then
                context.Server.Transfer(customErrorsCollection.Get(statusCode.ToString).Redirect)
            Else
                context.Response.Flush()
            End If
        End If
    End Sub
End Class

April 14, 2009

Map file extension to ASP.Net

Filed under: Uncategorized — Tags: , — chrishaas @ 9:24 pm

I’m converting a site from static HTML to dynamic ASP.Net but I don’t want to rename every page or worry about dropping in pages in the search engines. So I decided to just map HTML files to the ASP.Net processor. I could have sworn that I had done this before and all I had to do was make the normal IIS setting change (http://msdn.microsoft.com/en-us/library/bb515343.aspx). But that just returned a blank page. The fix is to add a buildProvider and an httpHandler.

<configuration>
    <system.web>
        <compilation debug="false">
            <buildProviders>
                <add extension=".html" type="System.Web.Compilation.PageBuildProvider"/>
            </buildProviders>
        </compilation>
        <httpHandlers>
            <add verb="*" path="*.html" validate="false" type="System.Web.UI.PageHandlerFactory" />
        </httpHandlers>
    </system.web>
</configuration>

Blog at WordPress.com.