Melvyn Harbour

Software Developer living in Cambridge, England and working for Red Gate

  • Red Gate's Down Tools Week

    Just a short post to kick off the week. As some people may now, the company I work for, Red Gate Software, is having a 'Down Tools' week, where we are free to work on any project we like. It's an opportunity to (hopefully!) write some cool code and try some things out.

     The project I'm going to be working on is attempting to add some level of support for F# to .NET Reflector. We're not sure how much of it we're going to be able to do, but we're really hopeful that we're going to be able to produce something by the end of the week that we're going to be able to put out there and let people have a go with. We'll try and keep you updated with progress as we go!


  • Using StackExchange to produce Ask SQL Server Central

    StackExchange has recently gone to beta, allowing people to set up sites using the same platform that runs StackOverflow. As my team maintains SQL Server Central, we decided to take advantage of this and set up Ask SQL Server Central. We’re not sure where we’re going to go with it yet, as it takes quite a different model to the rest of the site, which mainly features articles and traditional forums, but we felt that some people might find it a useful way of finding information, and it was pretty straightforward to do, so we dived in.

    One immediate offshoot of this is that StackExchange uses OpenID as its preferred method of sign in. In order to reduce the complexity for the current members of SQL Server Central, we’ve taken the decision to make SQL Server Central an OpenID provider, so that people can use their existing login for Ask SQL Server Central. This actually turned out to be a relatively straightforward process, as we used DotNetOpenAuth, which provides a pretty solid set of libraries to help you achieve exactly what we wanted to. In fact we were largely able to use much of the sample code they provide, with very few changes required (the hardest being to cope with some of the URL rewriting we have going on). We haven’t gone fully live with this, as we want to check that the hookup works fine before letting everyone use it, but it should appear within the next couple of days.

    The next exciting step from there will be to allow users to log into SQL Server Central using an OpenID from somewhere else, and hence permit us to pick up things like Gravatars. Hopefully DotNetOpenAuth should help us with this again.


  • Automated Web Testing

    One of the things about ASP.NET MVC that's particularly pushed is how easy it makes unit testing. Another aspect I think is particularly exciting is improving the ability to perform automated front-end testing. One of our web testers here at Red Gate has started looking into this and seeing what can be done to add automated front end testing to some of the sites we look after. He's put the first post of a series looking into this up at:

     Adventures in Web Testing: Combining xUnit.NET and Selenium


  • Combining ASP.NET MVC and ASP.NET Charting Controls

    As ScottGu recently posted on his blog, Microsoft have recently released a set of charting components. Several people followed up with comments on his post asking whether it was possible to use them with ASP.NET MVC. The good news is that it certainly is, if you are using ASP.NET as the View engine (the default). And there's actually relatively little that you have to do. This post outlines the steps you'll need to take to get it up and running.

    You'll need to first add the references to the appropriate assemblies (System.Web.DataVisualization and System.Web.DataVisualization.Design if you want design support). You also need to add a couple of lines to your Web.Config file. In the <controls> section, you will need to add:

       1: <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting" assembly="System.Web.DataVisualization, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

    You'll also need to add a new line to the httpHandlers section:

       1: <add path="ChartImg.axd" verb="GET,HEAD" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

    It's then pretty much simplicity itself to add a chart to a view page - you just drop it on as a server control exactly as in the examples in the sample project linked for Scott's post. You'll obviously need to call the code to insert the DataPoint objects into an appropriate Series, and this will probably lead to a few lines of code in the code behind file, but given that the data-transfer objects between the controller and the view are generally reasonably well structured, this code should be both readable, and fairly short, so I don't think that it's really a problem.

    I think the best approach if you are interested in doing this is to simply have a go and see how it gets on. I think it's a nice simple solution myself and certainly doesn't represent a great deal of overhead to get the result out.


  • MVC ModelBinder and Localization

    One of the great things about the way in which the Microsoft ASP.NET MVC Framework is being developed is the fact that the team are publishing the source code as they go along. This makes it very simple to dig into the framework when something slightly surprising is happening and figure out exactly how it is supposed to work. A good example of this cropped up for us yesterday when looking at a form posting scenario using DateTimes. We were dealing with an Action Method that looked something like this:

       1: public ActionResult DoSomething(DateTime theDate)
       2: {
       3:     return View();
       4: }

    And using the automatic model binding infrastructure to set the method parameter from a form. Naturally, being based in England, we were not totally shocked when we ran into localization issues almost immediately with this. It appeared at first glance that the date was being parsed assuming en-US format (mm/dd/yyyy), whereas for the application we were writing, which will be used internally be people who will expect to use en-GB (dd/mm/yyyy), we wanted it to parse in a different format. This prompted some investigation to discover what the framework was using to make its decision about which culture to use. The result turned out to be somewhat more clever than we had first thought, and nicely illustrates the way in which MVC Framework applications should be structured.

    The initially surprising piece of information that it transpires that it actually matters whether you have set the HTTP method to be a GET or a POST. To understand why this is the case, here is a snippet from within the MVC source code. I have removed several lines from the code to make it easier to see what is going on. If you want to see the original, it is within GetValue(string name) of System.Web.Mvc.DefaultValueProvider.

       1: CultureInfo culture = CultureInfo.InvariantCulture;
       3: if (request.QueryString != null)
       4: {
       5:     rawValue = request.QueryString.GetValues(name);
       6: }
       7: if (rawValue == null && request.Form != null)
       8: {
       9:     culture = CultureInfo.CurrentCulture;
      10:     rawValue = request.Form.GetValues(name);
      11: }

    In other words, when looking for the value to parse, the framework looks in a specific order namely:

    1. RouteData (not shown above)
    2. URI query string
    3. Request form

    Only the last of these will be culture aware however. There is a very good reason for this, from a localization perspective. Imagine that I have written a web application showing airline flight information that I publish online. I look up flights on a certain date by clicking on a link for that day (perhaps something like, and then want to email that link to my colleague in the US. The only way that we could guarantee that we will both be looking at the same page of data is if the InvariantCulture is used. By contrast, if I'm using a form to book my flight, everything is happening in a tight cycle. The data can respect the CurrentCulture when it is written to the form, and so needs to respect it when coming back from the form.

    But this brings us back to a consideration of the HTTP method that has been used. Remember that if we set the form to be HTTP GET, when the form is submitted the values of the fields in the form will be turned into a query string. So they will be parsed with the InvariantCulture rather than the CurrentCulture, as they would have been if it were an HTTP POST. We can therefore toggle the behaviour of the form (from a localization standpoint) by changing the HTTP method.

    Now to me this seemed slightly surprising at first, but I can certainly see that from the framework authors' perspective, it's the correct way of doing things. It still does leave one loose end, from a technical perspective. Suppose now that out airline flight information application allows the user to type in a date for which they wish to view flight information rather than clicking on a (computer generated) hyperlink. This is not an unreasonable behaviour, and is probably far more realistic of the way that the application would in fact be written. I still want the form to submit via HTTP GET rather than POST, as I want a URL to be generated that my user could email to his colleague. Effectively therefore, I have mandated that the user needs to enter the date using the InvariantCulture, which is hardly very localization friendly! If the application is only going to be used by people in (for example) en-GB (as might be the case for a company internal application), it is very possible that the date format will be known, and specified.

    Help is at hand though! Luckily, the way that the MVC Framework has been written makes it very easy for us to drop in other components to ensure that specific parts of the application such as this run the way that we expect them to. In this instance, what we want to do is register a new ModelBinder that will handle this DateTime to parse it using a specified culture. Writing a new ModelBinder is actually staggeringly simple. All we need to do is implement IModelBinder, and then register the new ModelBinder in Global.asax.cs. A very simple example of a custom ModelBinder to force the binding of DateTimes to always use en-GB is given below.

       1: public class MyBinder : IModelBinder
       2: {
       4:     #region IModelBinder Members
       6:     public ModelBinderResult BindModel(ModelBindingContext bindingContext)
       7:     {
       8:         string theDate = bindingContext.HttpContext.Request.QueryString["theDate"];
       9:         DateTime dt = new DateTime();
      10:         bool success = DateTime.TryParse(theDate, CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out dt);
      11:         if (success)
      12:         {
      13:             return new ModelBinderResult(dt);
      14:         }
      15:         else
      16:         {
      17:             // Return an appropriate default
      18:         }
      19:     }
      21:     #endregion
      22: }

    We then just need to tell MVC to use the ModelBinder. All this takes is a line in Global.asax saying:

       1: ModelBinders.Binders.Add(typeof(DateTime), new MyModelBinder());

    Of course the custom ModelBinder could be modified to do anything else that you want to, or indeed descend from DefaultModelBinder, and use other properties of the binding to help it determine whether it should use the new behaviour, or leave it up to the original DefaultModelBinder. The above example isn't particularly realistic in that we have mandated that the value of a DateTime will be coming in on a query string parameter of 'theDate'. It would normally be the case that we would use other properties of the ModelBindingContext to be more accurate about the situations we need to override. The ModelBinder could also be specified explicitly using an attribute on the method parameter.

    On a side note, I thought it would be worth linking to an article featuring Red Gate's biggest fan!


  • C# 4.0 Duck Typing and mocking extension methods

    Seeing some of the early blog posts from people who are at PDC, I have thus far been paying most attention to the information starting to come out about C# 4.0. In particular, this focus will look at Dynamic Lookup and the dynamic type. In particular, this should be able to be used to solve a problem with mocking objects where you are using extension methods.

    As a reminder, extension methods were introduced in C# 3.0 and enable you to 'add' methods to a class, even if that class is beyond your direct control, or is a sealed class. The canonical example would be adding a method such as 'Reverse' to the (sealed) String class. This would typically look something like (source: Wikipedia):

       1: public static class Utility
       2: {
       3:     public static string Reverse(this string input)
       4:     {
       5:         char[] chars = input.ToCharArray();
       6:         Array.Reverse(chars);
       7:         return new String(chars);
       8:     }
       9: }

    All fairly standard so far and nothing particularly dramatic. The interesting question comes if (for example) you were Unit Testing an application involving a class with an extension method that you want to mock. In fairness, this might not be going to happen every day, but is in fact a very similar problem to that that Phil Haack faced with trying to mock the HttpContext class. In both cases, we are faced with a method that you cannot mock. In Phil's case, because the classes HttpRequest and HttpResponse are sealed, and this case, the fact that the extension method isn't actually part of the class means that a mocking framework cannot offer an override for it.

    Let us create a simple example, using the above utility class:

       1: public class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         Demo demo = new Demo(new TextProvider());
       6:         Console.WriteLine(demo.Example());
       7:         Console.ReadKey();
       8:     }
       9: }
      11: public class Demo
      12: {
      13:     ITextProvider Provider;
      15:     public Demo(ITextProvider input)
      16:     {
      17:         this.Provider = input;
      18:     }
      20:     public string Example()
      21:     {
      22:         return Provider.Reverse();
      23:     }
      24: }
      26: public class TextProvider : ITextProvider
      27: {
      28:     public string Text
      29:     {
      30:         get { return "Monkey"; }
      31:     }
      32: }
      34: public interface ITextProvider
      35: {
      36:     string Text { get; }
      37: }
      39: public static class Util
      40: {
      41:     public static string Reverse(this ITextProvider input)
      42:     {
      43:         char[] chars = input.Text.ToCharArray();
      44:         Array.Reverse(chars);
      45:         return new String(chars);
      46:     }
      47: }

    Apologies for the rather contrived example, but it should serve the purposes of illustration. Now let us set up an attempt to test the Example method. In the example below I will be using, but which framework is used is rather unimportant.

       1: public class DemoTest
       2: {
       3:     [Fact]
       4:     void ExampleReversesMonkey()
       5:     {
       6:         // Arrange
       7:         Demo demo = new Demo(new TextProvider());
       9:         // Act
      10:         string result = demo.Example();
      12:         // Assert
      13:         Assert.Equal("yeknoM", result);
      14:     }
      15: }

    And this compiles and runs just fine, and we pass the unit test, which is all good. But suppose that rather than passing a real 'TextProvider', we want to pass in a mocked version. Using Moq, we might expect to modify the test to look something like this:

       1: [Fact]
       2: void ExampleReversesMockedString()
       3: {
       4:     // Arrange
       5:     var mock = new Mock<ITextProvider>();
       6:     mock.Expect(x => x.Text).Returns("Monkey");
       7:     Demo demo = new Demo(mock.Object);
       9:     // Act
      10:     string result = demo.Example();
      12:     // Assert
      13:     Assert.Equal("yeknoM", result);
      14: }

    All fine so far - this builds and runs without any problem. So lets take it a stage further and rather than just mocking the Text property, let's mock the Reverse method as well by adding this line:

       1: mock.Expect(x => x.Reverse()).Returns("yeknoM");

    Suddenly everything's changed. Instead of running successfully, we now get a run time exception from telling us "Invalid expectation on a non-overridable member: x => x.Reverse()". And indeed there is no way for us to mock an extension method. But fear not, help looks to be shortly at hand. The dynamic lookup features of C# 4.0 will nicely address this problem, if we want our class to remain unit testable. Obviously details of exactly how the syntax is going to work are a little sketchy at this stage, but the idea would be to change the Example method of the Demo class to be something like:

       1: public string Example()
       2: {
       3:     dynamic d = Provider;
       4:     return d.Reverse();
       5: }

    And with basically no more changes, we should be back in business. The exact way that we mock the object will have to change since the mocking framework must not attempt to override the method, but we have at least opened up options for ourselves again.


  • How to use the ASP.NET MVC ModelBinder

    One of the new features in the latest build of ASP.NET MVC is the ModelBinder, which is provided to allow Action methods to take complex types as their parameters. Previously, action methods were only able to take simple types such as strings and integers as their parameters. The new ModelBinder provides the facility to build complex types from component parts that (for example) may be part the result of submitting a form with several fields. To see an example of this in action, we will first need a fairly simple class to work with. The following class definition will typically be placed in the Models directory. I have left the using statements at the start of the file as an 'exercise for the reader'!

       1: public class MBTest
       2: {
       3:     public string Name { get; set; }
       5:     public MBTest()
       6:     {
       7:     }
       8: }

    All fairly standard stuff. Now let's create a form on our index page that we can use to have a play with one of these objects:

       1: <% using (Html.Form("Home", "About")) { %>
       2:     <input type="text" name="Name" />
       3:     <button type="submit">Submit</button>
       4: <% } %>

    Again, just the relevant form supplied here, and kept as simple as possible for clarity. Nothing in the routing needs to change: that will all happen just fine. Now, the aim is to write an Action Method that looks like the following:

       1: public ActionResult About(MBTest testItem)
       2: {
       3:     ViewData["Title"] = "About Page";
       5:     return View();
       6: }

    Admittedly, this method doesn't actually do anything with the testItem object that it creates, but it could quite easily if it wanted to. What we want is that the Name property of testItem is populated with the contents of the text input field in our form. Previously, we would have done this by inserting code into the About method above to parse the results coming back. So here's the new bit. We create a helper class that will carry the knowledge of how to perform the translation from the form to the complex type. This class must implement the new interface IModelBinder.

       1: public class MBTestBinder : IModelBinder
       2: {
       3:     #region IModelBinder Members
       5:     public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
       6:     {
       7:         MBTest instance = new MBTest();
       8:         instance.Name = controllerContext.HttpContext.Request["Name"];
       9:         return instance;
      10:     }
      12:     #endregion
      13: }

    Obviously this is a very simple example, and I haven't used most of the information passed to the GetValue method, but the intention of this post is primarily to be a starting point, just to get you 'up and running'. So the MBTestBinder class functions as a bridge, in a similar way to an ADO.NET DataAdapter. There's one final step to getting this all hooked up, and that's to tell the code to use MBTestBinder. This is done by applying the new ModelBinderAttribute to things. There are actually two different places you can use this attribute, with the same effect. The first is by decorating the model class:

       1: [ModelBinder(typeof(MBTestBinder))]
       2: public class MBTest

    The second is decorating the parameter of your Action Method directly:

       1: public ActionResult About([ModelBinder(typeof(MBTestBinder))]MBTest testItem)

    My guess is that they've left the choice in because the decision about exactly where bridge classes such as MBTestBinder actually lives is not a straightforward one. Others will no doubt contribute much more involved examples and discuss whether this solution to the problem is even the correct one, but hopefully this post explains enough to enable people to get started with experimenting with it and getting a feel for it.


  • ASP.NET MVC Codeplex Preview 5

    ASP.NET MVC Codeplex preview 5 went live last night. Available here. I haven't had a dig into it yet to have (just downloading now), but according to the release notes, some of the highlights include:

    • More support for partial view rendering
    • Moving AJAX support into its own namespace (System.Web.Mvc.Ajax) to make it easier to swap it out and replace it with your own choice, such as jQuery.
    • Complex types as parameters of action methods (some discussion of this already in my post and the associated forum thread).
    • Various other tweaks and improvements particularly to helper methods.

    The source code apparently follows shortly!