Is SQL Server Profiler showing Connection Pooling not working?

TL;DR: No – it’s just SQL Profiler not telling you the entire truth.

In evaluating Entity Framework 4.1 (aka EF Code-First or “Magic Unicorn” Edition) I’ve been keeping an eye on what SQL it’s actually executing against SQL Server (how’s that for a leaky abstraction?). Here I saw something slightly worrying which was that it appeared that the client was logging in, executing a query and then logging out as seemingly indicated by the Audit Login and Audit Logout events:

image

The same thing happens without EF using basic SqlCommand queries. To tell you the truth I’d noticed this a while ago but hadn’t got round to investigating.

Rather than assume that connection pooling was broken on my machine, I had a hunch that SQL Profiler was somewhat misrepresenting what was really going on.

Indeed Markus Erickson on StackOverflow mentions the EventSubClass column you can add to SQL Profiler’s output to see if those Audit Logon/Logout events are actually connections being pulled from the pool or fresh connections.

Here’s how you show the EventSubClass column in SQL Profiler (I’m running SQL 2005 on this machine, I can only assume it’s similar on 2008):

  • Go to the Trace Properties window and switch to the Events Selection tab.
  • Click on the Show all columns checkbox
  • Scroll to the right and locate the EventSubClass column and check both checkboxes:

  • Then go to Organize Columns and move the EventSubClass column up so that it’s next to EventClass:

image

Now you can re-run your trace and hopefully be reassured that connection pooling after all is functioning correctly!

image

Hope that helps!

Running IISExpress without a console window

I created a little Windows Script file that you can put in the root of a site that when double-clicked will run IIS Express without its usual accompanying console window.

IIS Express seems to require a parent process so you have to keep the calling process alive whilst it’s running. The lowest tech way I could think of doing this is to use Windows Script Host’s WScript.Run method that allows you to spawn processes in a hidden window and wait for them to exit.

You can view and download the code here.  https://gist.github.com/864322

Just place the IISExpress.js in the root of your website and double-click, it should then launch your browser at the root of the site. You can adjust the port and CLR version by tweaking the variables at the top of the script.

Hope it helps!

Executing Cygwin Bash scripts on Windows

I was reading Jeremy Rothman-Shore’s post regarding kicking off a Cygwin script from a Windows batch file which addresses two things:

  1. Invoking Cygwin’s Bash, passing it a shell script to execute
  2. Resolving the script’s directory in bash so that it can access other resources its directory.

Here I want to improve a bit on the first point and come up with:

  • A general purpose “shim” that will execute a shell script on Windows in Cygwin
  • Will pass through any command-line arguments
  • Doesn’t trip up on any spaces in the path

The idea is that if I have a shell script called foo.sh, I create a Windows equivalent called foo.cmd alongside it that can be called directly on Windows without the caller worrying about Cygwin etc (apart from having it installed):

image

(Or foo.bat – I prefer the *.cmd extension because this isn’t MS-DOS we’re running here).

The CMD script has to:

  1. Find its fully-qualified current location and locate its *.sh counterpart
  2. Translate this Windows-style path into a Unix style path
  3. Pass this to Cygwin’s bash along with any other arguments

Firstly, finding a batch file’s location is similar to how it’s done in Unix: it’s the first argument to the script. So in our case we use %0, and we can extract parts of the path like so: %~dp0 will extract the drive and path from argument 0 (i.e. the directory). See the for command for more information on this funky %~ syntax.

Secondly, the translation from a c:\windows\style\path to a /unix/style/path is done by Cygwin’s cygpath command. We do this in a slightly roundabout way via the ever versatile for command.

Thirdly, arguments passed to a batch file can either be accessed individually using $1, %2, $3 etc, or all in one go using %*, which is what we use here.

In addition, so that we don’t litter the Cygwin environment with temporary variables that we’ve created, we use a little setlocal/endlocal trick.

Here it is:

@echo off
setlocal

if not exist "%~dpn0.sh" echo Script "%~dpn0.sh" not found & exit 2

set _CYGBIN=C:\cygwin\bin
if not exist "%_CYGBIN%" echo Couldn't find Cygwin at "%_CYGBIN%" & exit 3

:: Resolve ___.sh to /cygdrive based *nix path and store in %_CYGSCRIPT%
for /f "delims=" %%A in ('%_CYGBIN%\cygpath.exe "%~dpn0.sh"') do set _CYGSCRIPT=%%A

:: Throw away temporary env vars and invoke script, passing any args that were passed to us
endlocal & %_CYGBIN%\bash --login "%_CYGSCRIPT%" %*

Note that you just name this the same as your shell script with a .cmd or .bat file extension. and then just execute it as normal.

For example for the following shell script called foo.sh:

#!/bin/sh
echo
echo "Hello from bash script $0"
echo "Working dir is $(pwd)"
echo
echo "arg 1 = $1"
echo "arg 2 = $2"
echo

Here’s me calling it from Windows:

image

Hope that helps!

SOLVED: Windows Identity Foundation – “The system cannot find the file specified”

I’ve been working on a proof of concept for using claims-based authorisation with Windows Identity Foundation (WIF) against an Active Directory Federation Services (ADFS) 2.0 security token service (STS).

I seemed to have everything in place but came up against the following error in a yellow screen of death:

System.Security.Cryptography.CryptographicException: The system cannot find the file specified.

image

Looking at the stack trace it seems that Data Protection API (DPAPI which in .NET is exposed as System.Security.Cryptography.ProtectedData) is being used to encrypt data. A common use of DPAPI is to do encryption without you having to worry about key management: you leave it to Windows to worry about where the keys are stored. Those keys are typically buried in your user profile/registry somewhere – so it seemed odd DPAPI was being used here at all – the DPAPI keys would need to be part of the App Pool user account profile/registry.

Anyway, to cut a long story short I wasn’t Reading The Fine error Message fully. The interesting/useful bit was scrolled horizontally off-screen:

[CryptographicException: The system cannot find the file specified.]
System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope scope) +681

Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Encode(Byte[] value) +121
[InvalidOperationException: ID1074: A CryptographicException occurred when attempting to encrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ]
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Encode(Byte[] value) +1280740
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +74

Sure enough WIF was using DPAPI to encrypt a token, but DPAPI was complaining it couldn’t get to the keys because there was no user profile for the App Pool identity, which in this case Environment.UserDomainName/UserName told me was “IIS APPPOOL\DefaultAppPool” – and there was no such user profile directory under C:\Users.

So sure enough in IIS, in the advanced settings for the App Pool, Load User Profile was false, and setting it to true creates and loads user profile (a “DefaultAppPool” profile directory appeared in C:\Users), and the application worked:

image

Typically WIF tutorials use the ASP.NET Web Sites, which use Cassini for testing, which runs under the current user identity and therefore a user profile with its DPAPI keys will be loaded – which is why if you use the standard run throughs/demos you don’t come up against this issue. But if you run as a Web Application under “real” IIS, this is when you may hit this problem.

It’s also debatable whether the use of DPAPI here is at all sensible. In a web farm environment the DPAPI keys for the App Pool identities across servers will be different, so if you don’t have sticky sessions enabled on your load balancer you run the risk of such federated logins not working 100% of the time. This issue is mentioned by Matias Woloski in the Geneva forums.

Another case of bad defaults all round.

Chrome Extension: Amazon UK Search and Switch

I created a very simple Google Chrome extension that:

  • Allows you to search Amazon UK with a right-click
  • Switch back and forth between the UK and US versions of a page

Install it from the Chrome Extensions site.

The latter feature I find myself using all the time. If you follow, say, a book recommendation link to the .com site, but you want to buy  it on the .co.uk site. Alternatively, you may be reading a handful of reviews on the UK site, but over on the US site, there are lots more. When you’re on the Amazon.co.uk/.com site a “page action” icon will appear which, when clicked, will simply replace the amazon.co.uk in the URL with amazon.com or vice-versa.

It was incredibly simple to create. (It took longer to create the icons than write the code!) Extensions are essentially web pages that run in the background and have access to an API for interacting with Chrome: e.g. chrome.contextMenus, chrome.tabs, etc

For example: the search menu was created like so:

chrome.contextMenus.create({
    title: "Search Amazon.co.uk for '%s'",
    contexts:["selection"],
    onclick: function (info, tab) {
        var query = info.selectionText;
        chrome.tabs.create({
            selected: true,
            url: 'http://www.amazon.co.uk/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=' + encodeURIComponent(query)
        });
    }
});

To look at the rest of the source go to the install page, right click the Install button, save the CRX file and unzip it.

In future, I may add an options page so it’s not hard-coded for the UK/US sites and to selectively enable/disable the features.

Hope you find it as useful as I do.

Running the Less.js command-line compiler on Windows

There have been some interesting developments recently in the field of CSS pre-processors. CSS pre-processors work around the very limited syntax of CSS by allowing you to create your stylesheets using a more powerful, expressive syntax which then gets turned into plain CSS for consumption by all the main browsers. A couple of ones that I’ve come across are SASS and LESS. LESS is the one I’ve felt most comfortable with because it’s simply an augmentation of the CSS which allows you to incrementally introduce its syntax into your stylesheets.

For example LESS supports variables:

@brand_color: #4D926F;
#header {
   color: @brand_color;
}
h2 {
   color: @brand_color;
}

nested rules:

#header {
  color: red;
  a {
    font-weight: bold;
  }
}

…mixins, operations on colors and size, etc. Check out the  lesscss.org homepage for more.

LESS was originally a Ruby gem, but now also has implementations on ASP.NET (dotlesscss.org) and PHP. LESS has now (inevitably) been re-implemented in JavaScript by Alexis Sellier (github.com/cloudhead/less.js). As well as supporting pre-processing *.less files into *.css via the command-line, it can also be actually run live, directly in your browser!

<link rel="stylesheet/less" href="stylesheets/main.less" type="text/css" />
<script src="script/less-1.0.38.min.js"></script>

I’m not sure I’m quite ready to take the plunge running it live, in-browser on sites just yet, although maybe I shouldn’t be according to Dmitry Fadeyev:

Wouldn’t live processing lag? Not really. Two reasons for this. One: Less.js has been written from the ground up for great performance, so even browsers with poor JavaScript implementation should still run it very well (Less.js is about 40 times faster than the Ruby implementation—so suffice to say it’s a lot faster.). Two: On modern browsers that support HTML5, Less.js will cache the generated CSS on local storage, making subsequent page loads as fast as pure CSS.

Running on Windows

The command-line compiler lessc is targeted to *nix-based platforms and requires node.js which, the last time I checked, doesn’t run on Windows (UPDATE: it runs fine under Cygwin, there’s a nice simple standalone version here). But Windows has had the ability to run JavaScript directly since the 1990’s using Windows Script Host. So I took the latest distribution copy of less.js from GitHub at https://github.com/cloudhead/less.js/tree/master/dist/ and included it via a *.wsf file and stubbed/faked/implemented a few things like window, document and XMLHttpRequest that less.js assumes will be present (which are presumably provided by node.js?), and added a bit of command-line argument handling.

Download

Browse the code and download from GitHubhttps://github.com/duncansmart/less.js-windows and feel free to fork it and send me pull requests!

Usage

To use it, invoke lessc.wsf via cscript.exe like so:

cscript //nologo lessc.wsf input.less [output.css] [-compress] 

I’ve also added a less.cmd shim which will simplify it to just:

lessc input.less [output.css] [-compress] 

If you don’t specify an output.css the result is written to standard output. The -compress option minifies the output. I’ll look into implementing the other command-line arguments supported by lessc in due course.

I’ve added a couple of test files, so you can see if it’s working like so:

C:\code\lessc-wsh>lessc test.less
/* Variables */
#header {
  color: #4d926f;
}
h2 {
  color: #4d926f;
}
/* Mixins */
#header {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
...

Future

I may look into hooking this into Visual Studio’s T4 support so that the *.css files are generated as soon as you save the *.less files in Visual Studio. (UPDATE: See Phil Haack’s T4CSS that does this, instead using  the .NET port of LESS. Thanks to David De Sloovere for pointing this out.)

Update

Mark Lagendijk has created a nice little Windows GUI for the script. Check it out at http://winless.org.

Follow @duncansmart on Twitter

SOLVED: “The type initializer for ‘System.Drawing.ToolboxBitmapAttribute’ threw an exception”

This exception has been plaguing our automated error reports inbox for a while:

System.TypeInitializationException: The type initializer for 'System.Drawing.ToolboxBitmapAttribute' threw an exception. 
  ---> System.Runtime.InteropServices.ExternalException: GDI+ is not properly initialized (internal GDI+ error).
  at System.Drawing.Bitmap..ctor(Stream stream)
  at System.Drawing.ToolboxBitmapAttribute..cctor()
  --- End of inner exception stack trace ---
  at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
  at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
  at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
  at System.RuntimeType.GetCustomAttributes(Type attributeType, Boolean inherit)
  at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectGetAttributes(Type type)
  at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectedTypeData.GetAttributes()
  at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
  at System.ComponentModel.TypeDescriptor.GetAttributes(Type componentType)
  at System.Web.UI.ViewStateModeByIdAttribute.IsEnabled(Type type)
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Control.SaveViewStateRecursive()
  at System.Web.UI.Page.SaveAllState()
  at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The page it occurs on is the login page of an ASP.NET WebForms app which happens to be the default.aspx page in the root of the site: a page that gets a lot of hits. It happened sporadically and was impossible to reproduce: likely some odd timing issue. But when it did happen, it brought the whole web app down.

There appears to be an official hotfix for System.Drawing.dll at http://support.microsoft.com/kb/975410. You will need to contact Microsoft Support for this though. Rather than use up one of our Microsoft Partner support hits, a quick, simple solution dawned on me.

Our solution

Looking at the stack trace, it’s clear that the issue occurs when the page’s ViewState is being serialised. Therefore, the solution (OK, more of a workaround) in our case was simply to disable ViewState on the page:

<@Page … EnableViewState="false" %>

Now this might not work for you because your page, or controls on your page may rely on ViewState. For example, if you have OnChange event handlers on textboxes: these rely on having the “before” stashed in ViewState. But we rarely use ViewState anywhere in the application, so it was especially galling that we’d left it enabled on one of the the busiest pages in the app.

Follow

Get every new post delivered to your Inbox.

Join 35 other followers