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.

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;
}

Repeater Failure and Disappearance on Row 28

I was working on an ASP.net application (1.1) the other day, changing the UI display of a page. This page basically consisted of a Repeater being populated with data from the DB, and binding javascript actions and styling info to the different rows to be output (each overall it was producing a Table, and each item was a TableRow). Although the look-and-feel was going to be changing, as well as the manner in which the data was to be retrieved, the actual data set up and binding was to remain the same as it had been. Piece of cake, right?

The programming was straight-forward enough. When I first tested the feature on a few records, it worked fine. However, when I tested it on more records, it didn’t work. And when I say that it didn’t work, I am not saying that I got back some ugly .Net exception. I mean that the HTML output by the server was completely devoid of the Repeater element. It was as if it just did not exist. Somehow, when I tried the load the page with a large number of records,  some weired thing happened in IIS that just completely abandoned the rendering of the Repeater element without even providing an error message. Completely weird.

After a couple of hours of debugging, I was able to determine that the error was not related to any specific data item. Rather, it always happened when outputting the 28th DataItem in the Repeater. 27 worked fine. 28 killed it. Racking my brain (and Google), I couldn’t find any reason why this would be happening. This exact same repeater worked fine on other pages, on the live site. There was no reason I could think of why this type of failure would happen, and why it would happen here.

My coworker SeanS suggested that perhaps this was related to my dev environment, perhaps some faulty memory or something like that. There was nothing else to go on and this did explain what was going on (and I knew that the feature worked for <28 rows), so I proceeded with development. And lo and behold, when I uploaded my changes to the staging site yesterday, it worked with any number of rows without any hitch-up.

Moral of the story: weird things happen on web servers and on dev machines. Not every error that you get is related to code (especially if the error is reported by the absence of output rather than an exception). If something like this is happening to you (and it is not reproducible on other platforms), it may very well be environment-related. Test this out before wasting more time and energy trying to sort it out through the code.