Double Event Execution in global.asax

The native events in global.asax will autowireup no matter what you do. If you explicitly handle the event, it will execute from the autowireup and from the Handles statement. Hilarity will ensue.

So to be clear, this is bad:

Private Sub Application_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRequestHandlerExecute
End Sub

This is good:

Private Sub Application_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs)
End Sub

jQuery UI AutoComplete Using an ASP.Net PageMethod Data Source

    $(document).ready(
    function () {
        var searchTextFieldName = "#" + $("#header_searchTextFieldName").val();
        var searchButtonName = "#" + $("#header_searchButtonName").val();

        //configure the autocomplete dropdown on the search textbox
        $(searchTextFieldName).autocomplete({
            source: myHistorySourceFunction,
            minLength: 0,
            select: myHistorySelectFunction
        });

        //call the server for the result set
        function myHistorySourceFunction(request, response) {
            $.ajax({
                type: "POST",
                url: "../default.aspx/myHistory",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    //filter the result set based on what the user has typed in the search textbox
                    data.d = $.grep(data.d, function (item) {
                        return (item.toLowerCase().indexOf(request.term.toLowerCase()) != -1)
                    });
                    //map the formatted, filtered result set for use by the autocomplete behavior
                    response($.map(data.d, myHistoryDataFormatFunction));
                }
            });
        };

        //format the result items
        function myHistoryDataFormatFunction(item) {
            return { label: item, value: item };
        };

        //trigger the search button click event
        function myHistorySelectFunction(event, ui) {
            window.setTimeout("$('" + searchButtonName + "').click()", 100);
        };

        //display the autocomplete dropdown when the user clicks in the textbox
        $(searchTextFieldName).click(function () {
            if ($(searchTextFieldName).autocomplete("widget").is(":visible")) {
                return;
            }
            $(searchTextFieldName).autocomplete("search", "");
        });
    });

Transforming Config Files

Recently I was experimenting with configuration transformations.  The actual use and mechanics of config transformations is beyond the scope of this discussion, but more information is available here: How to: Transform Web.config When Deploying a Web Application Project.  I added the transforms to a legacy web project, edited the various files, every thing was working swimingly.

And then I tried to build the solution through TFS Build.

The first challenge I encountered was the transform was trying to…well…transform.  The system was attempting to create the output web.config file, which is under source control and not writeable.  The solution to this is to exclude the web.config file from source control.

The next challenge was that because the system considers the web.debug.config, web.release.config, et. al. to be dependent on the parent web.config, they also get excluded from source control.  The solution to this one was a bit more elusive, since all the config files are considered to be a single unit.  Exclude one, exclude them all.  Turns out the excluded-ness is stored in the .vbproj.vspcc file in the web project.

""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "4"
"EXCLUDED_FILE0" = "web.config"
"EXCLUDED_FILE1" = "web.debug.config"
"EXCLUDED_FILE2" = "web.release.config"
"EXCLUDED_FILE3" = "web.template.config"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

Simply remove the EXCLUDED_FILE1/2/3 lines, change the NUMBER_OF_EXCLUDED_FILES to 1 and life is good.

Sticky Transaction Isolation Level in Pooled Connections

omg!  Why are we getting so many deadlocks on the web site?!

When you change the isolation level on a pooled connection, it stays changed.  If you want to run a few things in a higher isolation level and you set the level to Serializable on a TransactionScope, finish your work, and complete the TransactionScope, the connection is returned to the pool with the current isolation level.  It does not revert to its default isolation level.

Our friends at Microsoft say this is by design: Article ID: 972915.

If you set it up, set it back down before releasing the connection.

(X(1))

Recently we had a bizarre response from a server when attempting to access a web site.

If I browse to http://web_1.myweb.com/home/login.aspx, the web site redirects to http://web_1.myweb.com/(X(1))/home/login.aspx.

Turns out the (X(1)) is ASP.NET attempting to run in cookieless mode. The cuprit is the combination of the underscore in the URL and having your web configured to autodetect cookies:

    <authentication mode="Forms">
      <forms cookieless="AutoDetect" />
    </authentication>

Here’s the sequence of events:

I send a request for http://web_1.myweb.com/home/login.aspx.

The server responds with a 302 redirect to http://web_1.myweb.com/home/login.aspx?AspxAutoDetectCookieSupport=1 and will include a AspxAutoDetectCookieSupport=1 cookie.

Normally, your browser would respond with a request to the new URL with the added querystring, as well as the cookie, and the system would continue on, but with the underscore in the URL, your browser (up to and including IE10) doesn’t consider this to be a valid domain, so it doesn’t send the cookie back.

ASP.NET then goes into cookieless mode, according to this MSDN article: Understand How the ASP.NET Cookieless Feature Works.

The solution is to remove the underscore from your URL, or (if your application requires cookies) to change your cookieless setting to “UseCookies”.

MSDN article describing why IE doesn’t play nicely with underscores in a URL: Article ID: 241980.

Microsoft.ReportViewer Async Wait Control

Recently we updated our ReportViewer library from the Visual Studio 2008 version to 2010.  With the new version, the previously working wait control shown below was no longer rendering.

Alt

For the most part, the report viewer requires little configuration, but there are a couple properties that affect the display of this control.

Because the 2010 version is AJAX-enabled, you’ll need a script manager control on your page with the EnablePartialRendering property set to True.  This is the default value.  (Mine was previously set to False, which was the issue in this case.)

In the report viewer control, set the AsyncRendering property to True.  This is the default value.  The WaitControlDisplayAfter property is a red herring; it’s only used for subsequent postbacks, not during the initial laoding of the report.