ross dickinson: web and desktop software developer

You may have seen this lovely exception before;

System.Exception: An exception has been encountered in setting up the test SQLite database. 

---> NHibernate.HibernateException: Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=3.3.1.4000

---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. 

---> System.ArgumentException: Unable to find the requested .Net Framework Data Provider.  It may not be installed..

 This happens due to a limitation in the NuGet command line and TeamCity's usage of it. A very dumb hack we've found to make this work correctly is to put a direct reference to a type in the Sqlite library inside one of the unit test classes. No clue why it works, but it does.

Bug in Chrome's SVG font rendering

by Ross on October 11, 2013 at 12:43 PM under

I recently posted this bug on the Chromium bug tracker. There's a bug in Chrome when using SVG fonts for select tags. When the select tag is opened, all text becomes jumbled in an "off by one" situation. "ABC" becomes "BCD" and so on.

But, there's good news if you're only using SVG fonts to make up for areas where Chrome's font rendering lacks. It looks like they're finally working on fixing the rendering problems with ttf/otf/woff files using GDI instead of DirectWrite!

Can't Install Genuine Advantage ActiveX Control

by Ross on October 12, 2012 at 4:05 PM under

If you're having trouble downloading updates from Microsoft's website due to their annoying genuine advantage ActiveX crap, make sure you're attempting to download it in the 32 bit version of Internet Explorer. For whatever reason, in 64 bit Internet Explorer you'll be prompted to allow the installation but you won't get the actual installation prompt.

Updating NuGet Package Manager

by Ross on June 14, 2012 at 8:55 AM under Visual Studio

Unable to update NuGet Package Manager because you're seeing this error?

VSIXInstaller.SignatureMismatchException: The signature on the update version of 'NuGet Package Manager' does not match the signature on the installed version. Therefore, Extension Manager cannot install the update.

Just do the following:

  1. Run Visual Studio as administrator and uninstall the existing NuGet Package Manager through the extension manager.
  2. Close VS
  3. Go to Add/Remove Programs and make sure NuGet is uninstalled in there. Note that you can't just uninstall it from here, because VS will still think it's installed for some reason.
  4. Run the new NuGet installer.
  5. Done!

If you're trying to run a script using Internet Explorer's ActiveX interface(such as the WebBrowser control in .NET, or using WatiN), you might stumble on this error when trying to run arbitrary scripts through the interface. Either ActiveX or Internet Explorer itself does not like scripts with carriage returns for some reason. It might not solve your problem but worth checking out.

Alternative to Segoe UI

by Ross on May 2, 2012 at 9:14 AM under

If you're looking for a free, legal alternative to using Segoe UI on your website, you might want to check out Open Sans on Google Web Fonts. It's nearly identical to Segoe UI, only a really discriminating eye can tell the difference(capital S is a little wider, other subtle things).

Submitting a Nested Form in ASP MVC3

by Ross on February 3, 2012 at 7:06 PM under .NET | ASP.Net | MVC

In case you're using the jQuery unobtrusive ajax library with your ASP MVC3 site, you'll probably find that it can be difficult to submit a nested form in certain situations. The problem comes from this bit of code:

$("form[data-ajax=true]").live("submit", function (evt) {
    var clickInfo = $(this).data(data_click) || [];
    evt.preventDefault();
    if (!validate(this)) {
        return;
    }
    asyncRequest(this, {
        url: this.action,
        type: this.method || "GET",
        data: clickInfo.concat($(this).serializeArray())
    });
});

When your nested form's submit event gets raised, it bubbles up to the parent form as well. You can fix this in two ways. The easiest way is to modify the code above to look like this:

$("form[data-ajax=true]").live("submit", function (evt) {
    if (evt.currentTarget != evt.target) { return; }
    var clickInfo = $(this).data(data_click) || [];
    evt.preventDefault();
    if (!validate(this)) {
        return;
    }
    asyncRequest(this, {
        url: this.action,
        type: this.method || "GET",
        data: clickInfo.concat($(this).serializeArray())
    });
});

This stops the unobtrusive ajax library's handler from submitting the wrong form.

Another way is to add your own submit handler to your nested form that calls evt.stopPropagation(). This tells the event to stop bubbling up and calling other event handlers. This can be tricky, though, because you have to ensure that your handler is called before the unobtrusive handler.

What's ASP.Net's Request Validation Doing?

by Ross on January 12, 2012 at 4:16 PM under .NET | ASP.Net

I'm sure you've seen this before:

A potentially dangerous Request.Form value was detected from the client

Ugh! Annoying. So what's dangerous about the request? Could be anything, but let's break down what ASP does in the background when it actually validates the request.

1. Checks postback keys

This is almost inconsequential, but something worth pointing out. The HttpRequest class has a private method called ValidateNameValueCollection that determines whether or not a postback value should be be validated.  Oddly enough, this has nothing to do with checking whether the developer's supplied a way to bypass validation(like by using the ValidateInputAttribute in MVC). All this method does is make sure that that all of the keys are validated, unless the key begins with "__". I'm assuming this is here so fields like "__VIEWSTATE" don't break the validation.

2. Validate input

After the key's been checked, if the matching value isn't null, it's then passed to a series of a functions that check that the value

  1. Doesn't contain any text with an < followed immediately by any letter, !, ?, or / symbol. 
  2. Doesn't contain the text "&#"

That's it.

That's all it does.

I actually think catch-all validation like this is fairly useless for anyone with a little experience in web development, because trying to throw an exception when html tags are sent to the server isn't necessarily going to prevent them from being rendered back out to the client. The values should be sanitized before being sent back to the client, instead.

Getting MVC3 to load scripts from a Partial View

by Ross on January 6, 2012 at 12:37 PM under ASP.Net | MVC | AJAX | jQuery

On an MVC3 project I'm working on, one of the things we do when allowing a user to edit a record s open up an ajax form inside a jQuery UI Dialog. This is done through a really simple setup of

  1. Call controller action.
  2. Controller action returns a PartialViewResult.
  3. Using some custom hooks into the jquery.unobtrusive-ajax library, render the partial view into a dialog.

Seems simple enough, right? This works well, except if the partial view includes script tags. By design, when using $.append, jQuery will remove all the script tags in the created element, then attempt to load them via ajax before appending the main content. This can be a problem if the script you're loading depends on elements inside the partial view's content.

Luckily, there's an easy way to get around this. When you do something like:

var newElement = $('<div><script src='somewhere'></script></div>');

jQuery doesn't return an array with one element, it actually returns with two elements!

// Assuming you have Firebug or Chrome, you can use console.debug:
console.debug(newElement.length); // This will equal 2
console.debug(newElement[0]; // This will be the main content with the script tags removed
console.debug(newElement[1]); // This will be the script tag.

So jQuery's actually nice enough to give us back everything all organized before anything happens. If you need to load the scripts after the elements have been added to the DOM, you need to manually append everything instead of just calling $.append(newElement). Here's how to do it:

// Create a parent container to hold our content. If
// you already have a parent attached to the DOM,
// you can use that instead.
var $parent = $('<div></div>');

// Create an array to hold on to our script references.
var scripts = [];

// Append any elements that aren't scripts,
$newElement.each(function() {
	var el = $(this);
	// tagName is always all caps.
	if (el.prop('tagName') === 'SCRIPT') {
		scripts.push(el);
	}
	else {
		d.append(el);
	}
});

// If your parent element isn't attached to the DOM yet, you need to do
// that now before adding the scripts, otherwise any scripts that reference
// elements from the html fragment will fail.

$(document).append($parent);

// Now we just need to append each script from our scripts array.
// jQuery does this synchronously so the scripts will still load
// in the same order they were originally in.
$(scripts).each(function(i, script) {
	d.append(script);
});

TIP: Because your new elements will be displayed before your scripts are loaded, you should consider hiding them before the scripts are appended, and then show them afterwards.

If you're using Microsoft's unobtrusive ajax library with your MVC3 project, you might come across a problem if you're trying to add an error handler to one of your Ajax.BeginForm or Ajax.ActionLink calls.

The problem lies in the library's handling of the data-ajax-failure attribute that gets added to an ajax form/link. Basically, the library just doesn't execute the method after finding it. The problem line of code is line 98 of jquery.unobtrusive-ajax.js:

$.extend(options, {
    // other handler code removed
    error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
});

To fix this, you need to change line 98 to this:

 

$.extend(options, {
    error: function() {
        getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(this, arguments);
    }
});

About the author

rossisdead is a 26 year old web and desktop software developer from New Jersey. He has two cats and likes long walks on the beach.

On Stackoverflow

On Stackoverflow Careers

On Codeplex

On Github