Could not load type ‘System.Web.Razor.Parser.SyntaxTree.CodeSpan’ from assembly ‘System.Web.Razor

I am working with an ASP.net MVC4 project with WebAPI, and upgraded/installed a number of nuget packages (and stupidly did not test after each one). When the dust settled, I tried to load an API page in my browser and got the following error message:

“Could not load type ‘System.Web.Razor.Parser.SyntaxTree.CodeSpan’ from assembly ‘System.Web.Razor”

Eventually, I was able to resolve the error by removing the following from my web.config and app.config files:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <!-- Begin Remove -->
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
    </dependentAssembly>
    <!-- End Remove -->
  </assemblyBinding>
</runtime>

I would guess that one of the packages that I installed added this reference, which had a conflict with a different version of the same assembly in the GAC. In any event, it fixed the error (and did not cause any apparent new errors). Posting in case it may help you out with a similar error.

Force WebAPI to return JSON by Default for Html GET Requests

Currently, the default response type of for Web API requests is XML. By the time it comes out of beta, it will be the default (source - this is mentioned by Hanselman towards the end of the post). However, if you want to activate this right now, how should you do it?

Two steps:

  1. Set a JSON formatter as the first Formatter in the Web API Config Formatters collection
  2. Set “text/html” as an accepted media type for this formatter

WebAPI includes a JSON Serializer by default: DataContractJsonSerializer. However, no one wants to use it, and for good reason: lots of issues with different types, slow performance, bad date formatting and more.

Thankfully, WebAPI allows you to switch customize the data formatters used for different content types. Bloggers have recommended a number of different approaches. What seems to be the most promising is Henrik Nielsen’s JsonNetFormatter (using Json.NET to handle the JSON serialization) combined with a fix for a DateTime serialization issue (Hanselman also implies that this will be the default in post-beta WebAPI).

After you add the code for the JsonNetFormatter, you can set this up as the default Json data formatter by doing the following:

protected void Application_Start()
{
    ...

    JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
    serializerSettings.Converters.Add(new IsoDateTimeConverter());
    GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonNetFormatter(serializerSettings));

    ...
}

Once you have done this, any request that comes in to the API that asks for json (setting a header to accept content of type application/json, utilizing the facility in WebAPI for content negotiation) will receive Json content formatter using the JsonNetFormatter class. However, if you want to just test this out in your browser, you will still get XML content. This is because a plan request from your browser is for type text/html, which translates to xml in the Web API universe. Though the Json will be returned automatically if you explicitly request json content (or if you use a function that requests this content type, like the $.ajax function in jQuery), if you want to test out the json in your browser, you will be out of luck using the standard configuration.

To get around this, you need to set the JsonNetFormatter to support the “text/html” media type. This will allow it to respond to requests made from the browser (and since the JsonNetFormatter is now the first Formatter in the Formatters collection, it will be used by default). You can do this as follows:

protected void Application_Start()
{
    ...

    JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
    serializerSettings.Converters.Add(new IsoDateTimeConverter());
    var jsonFormatter = new JsonNetFormatter(serializerSettings);
    jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter);

    ...
}

Numeric String Sort in C#

Scenario: you have a List<string> collection where the contents could be alpha, numeric, or alphanumeric. If you just sort the collection using the built-in Sort() method, it will use string.CompareTo(), treating each item in the collection as a string. Thus a collection with the following values ["1", "44", "22", 4", "5"] will end up being sorted as ["1", "22", "4", "44", "5"] – even though you might want the items to be treated as numbers (in which case they would be sorted as ["1", "4", "5", "22", "44"].

The solution to this is to use a custom comparer class. I put the following together:

public class NumericStringSort : IComparer {

    int IComparer.Compare(string a, string b) {
        decimal aDec;
        decimal bDec;
        if (decimal.TryParse(a, out aDec) && decimal.TryParse(b, out bDec)) {
            return aDec.CompareTo(bDec);
        } else {
            return a.CompareTo(b);
        }
    }

    public static IComparer NumericStringSorter() {
        return (IComparer) new NumericStringSort();
    }
}

As you can see, the class implements the IComparer interface. If both of the strings can be converted into decimals, then the decimal comparison is used. Otherwise the string comparison is used.

You can see a usage example through the following set of unit tests (as you can see, it also handles mixed alphanumeric sets gracefully, sorting all numeric items to the front of the list in numeric order, followed by all alpha entries in alphabetical order):

[TestFixture]
public class NumericStringSortTests {

    [Test]
    public void TestNumericSort_AllNumeric() {
        List items = new List { "1", "44", "22", "4", "5" };
        items.Sort(NumericStringSort.NumericStringSorter());
        List expectedItems = new List { "1", "4", "5", "22", "44" };
        Assert.IsTrue(items.SequenceEqual(expectedItems));
    }

    [Test]
    public void TestNumericSort_MixesAlphaNumeric() {
        List items = new List { "a", "c", "d", "b", "1", "2", "22", "3" };
        items.Sort(NumericStringSort.NumericStringSorter());
        List expectedItems = new List { "1", "2", "3", "22", "a", "b", "c", "d" };
        Assert.IsTrue(items.SequenceEqual(expectedItems));
    }

    [Test]
    public void TestNumericSort_AllAlpha() {
        List items = new List { "a", "c", "d", "b" };
        items.Sort(NumericStringSort.NumericStringSorter());
        List expectedItems = new List { "a", "b", "c", "d" };
        Assert.IsTrue(items.SequenceEqual(expectedItems));
    }
}

This is something that I have needed on previous occasions – perhaps it may be of use to someone else.

Connecting to Excel and Access Files using .Net on a 64-bit Server

If you are trying to query a MS Excel (.xls, .xlsx, .xlsb) or MS Access (.mdb, .accdb) file on a 64-bit server and are getting one of the following error messages:

  • The ‘Microsoft.Jet.OLEDB.4.0′ provider is not registered on the local machine.
  • The ‘Microsoft.ACE.OLEDB.12.0′ provider is not registered on the local machine.

Then it is necessary to install 2010 Office System Driver Beta: Data Connectivity Components on the server (the reason for this is the old Jet4.0 drover does not exist for 64 bit, and the ACE driver needed to read the newer formats is not installed by default). If you are using a version of Windows with UAC enabled, be sure to do this as Administrator.

After installing the components, use the following connection string formats (from the page linked-to above):

  • Using OLEDB, set the Provider argument of the ConnectionString property to “Microsoft.ACE.OLEDB.14.0”. Example: “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Path_To_File”
  • Using OLEDB and connecting to a Microsoft Office Excel file, add “Excel 14.0” to the Extended Properties of the OLEDB connection string defined in the previous bullet point.
  • Using ODBC:
    • Connecting to Microsoft Office Access (.mdb or .accdb): set the Connection String to “Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=path to mdb/accdb file”
    • Connecting to Microsoft Office Excel (.xls, .xlsx, .xlsb): set the Connection String to “Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=path to xls/xlsx/xlsm/xlsb file”

Casting vs. Converting in .Net

I recently saw a piece of code in a project that was throwing an exception that I did not understand:

string boolString = (string)DataBinder.Eval(DataItem, "IsNew");

One would expect that boolString would be assigned the value “True” or “False” depending on the value of the IsNew property of the DataItem object. However, this through an Exception with the message: “Cannot explicitly convert bool to string”. What is going on here?

The syntax of (type)variable attempts to explicitly cast the variable into the given type. Casting does not attempt to interpret the data in the variable – it just tries to fit the object referred to by the variable into the new data type. This will work whenever the two types are somehow compatible (for example, an int can be cast into a float with no exceptions) though sometimes it may result in data loss (a float cast into an int). However, in cases where there is no connection between the two classes, casting will result in an Exception (like the one that I received above).

(There is another way to cast an object – using the as keyword. This will return a null if the cast fails, and is much faster than the explicit casting referred to above).

However, when converting an object, the conversion function has “knowledge” of the data contained in both the source and final object types, and will create the equivalent of the variable in the new data type. In the case above, using the System.Convert.ToString() method in place of the attempted cast to (string) would have worked fine. This is because the ToString method “knows” that a bool cannot be case into a string – but it also knows what the equivalent string to each value of a bool will be, and is able to process the operation accordingly. In this case, reflector uncovers the following code (in the Boolean class):

public string ToString() {
    if (!this) {
        return "False";
    }
    return "True";
}

This is obviously a very simple type conversion. However, there are many more complex conversion utilities built into the .Net framework (accessible through the System.Convert class – see the DateTime.ToString conversion for an example of this. Also see the IConvertible interface). While conversions can be more expensive to run, since they are strongly typed, they are checked at compile time, and when used properly are more reliable to use when producing stable code. (See the MSDN article on Casting and Type Conversions for more info).

Detecting Application Idle State in Windows Forms

On a recent project, I had the need to detect whether or not the application is idle, and if so, for how long has the idle state persisted. Idle in my case is defined as no mouse movement or keyboard activity when any of the forms of the application are in focus. If a different program is in focus, I define this as being an application-idle state (for my app), regardless of whether or not there is input activity from keyboard or mouse.

On researching the subject, I found several approaches. The main approach I have seen is to use the static Application.Idle event. This event fires whenever “application finishes processing and is about to enter the idle state” – In other words, whenever the application’s message queue is empty. The problem with this approach is that this event fires a lot, so much that it becomes impractical for tracking idle state the way that I need it (it doesn’t help that any Timer operating to track how long the idle state persists would set off Application.Idle, further complicating the situation).

The other approach that I have seen is to set up some Windows hooks to detect mouse and keyboard activity. I have zero experience operating with the Windows API, so thankfully, I found a post by Johan Danforth that gives some working code for doing exactly what I needed: Detecting Idle Time with Mouse and Keyboard Hooks. I integrated the code with my application and tested it out and it worked great.

There was one problem however: this code detects idle time for all applications. In other words, if your application is open but not in focus and you use your mouse or keyboard, the code changes your application status from Idle to Active. For my purposes (see definition if idle above) this is not good enough. So I inspected different properties of the System,Windows.Forms.Form class to see what could tell me whether or not a given form is active. The first candidates were Focused, TopLevel, TopMost and Visible, but none of these did the job. The property that ended up telling me exactly what I needed to know is ContainsFocus. This is a property of the Control class (from which Form inherits) and it “Gets a value indicating whether the control, or one of its child controls, currently has the input focus”. (Focused is not good enough, since it only returns true when the form itself has focus, but returns false when a child control contained within the form has focus).

I also needed to detect whether any of the secondary forms of my application had focus (since I could have more than one window open at a time, only one of which could have focus). Here is the code that I used:

private bool DoesApplicationHaveFocus() {
  bool hasFocus = false;
  if (ContainsFocus) {
    hasFocus = true;
  } else {
    FormCollection forms = Application.OpenForms;
    foreach (Form f in forms) {
      if (f != null && f.ContainsFocus) {
        hasFocus = true;
        break;
      }
    }
  }
  return hasFocus;
}