Tasks that throw exceptions

I’ve blogged before about the AggregateException in .NET 4, but I missed out something that may be important. If you are using Parallel.Invoke or Parallel.For or Parallel.ForEach or PLINQ you probably won’t notice this because each of these constructs block until all the tasks are completed. However, if you are using Task.Factory.StartNew() then this may be important.

The AggregateException won’t bubble up into the calling thread or task until one of the Wait… methods (excluding WaitAny) is called.

This means that any number of exceptions can be happening but the thread that starts the task may not know about it for some time if it is getting on with other things itself.

Take this code for example:

class Program
{
    static void Main(string[] args)
    {
        // Start the tasks
        List<Task> tasks = new List<Task>();
        for (int i = 0; i < 20; i++)
        {
            Task t = Task.Factory.StartNew(PerformTask);
            tasks.Add(t);
        }

        Console.WriteLine("Press enter to display the task status.");
        Console.ReadLine();

        // Display the status of each task.
        // If it has thrown an exception will be "faulted"
        foreach(Task t in tasks)
            Console.WriteLine("Task {0} status: {1}", t.Id, t.Status);

        Console.WriteLine("Press enter to wait for all tasks.");
        Console.ReadLine();

        // This is where the AggregateException is finally thrown
        Task.WaitAll(tasks.ToArray());

        Console.ReadLine();
    }

    public static void PerformTask()
    {
        Console.WriteLine("Starting Task {0}", Task.CurrentId);
        throw new Exception("Throwing exception in task "+Task.CurrentId);
    }
}

At the start of the program it starts 20 tasks, each of which throws an exception. The output of the program at this point is:

Press enter to display the task status.
Starting Task 2
Starting Task 1
Starting Task 4
Starting Task 3
Starting Task 5
Starting Task 7
Starting Task 6
Starting Task 8
Starting Task 9
Starting Task 10
Starting Task 11
Starting Task 12
Starting Task 13
Starting Task 14
Starting Task 15
Starting Task 17
Starting Task 16
Starting Task 18
Starting Task 19
Starting Task 20

The reason the "Press enter to display the task status" appears on the first line is that the main thread is still running and performing operations as the background tasks are still spinning up.

Then each of the tasks are started and each output a simple line to the console to prove they are there. Then each throws an exception, so far unseen (other than for the debugger breaking the running on the program to tell the developer, but in a production system you are not going to have that.)

Now, the application is paused on a Console.ReadLine() waiting for the user to press enter. The application is still running merrily.

If the enter key is pressed the next bit of output is displayed:

Task 1 status: Faulted
Task 2 status: Faulted
Task 3 status: Faulted
Task 4 status: Faulted
Task 5 status: Faulted
Task 6 status: Faulted
Task 7 status: Faulted
Task 8 status: Faulted
Task 9 status: Faulted
Task 10 status: Faulted
Task 11 status: Faulted
Task 12 status: Faulted
Task 13 status: Faulted
Task 14 status: Faulted
Task 15 status: Faulted
Task 16 status: Faulted
Task 17 status: Faulted
Task 18 status: Faulted
Task 19 status: Faulted
Task 20 status: Faulted
Press enter to wait for all tasks.

This time the "Press enter to wait for all tasks." message appears at the end of the list. This is because everything here is being written from the main thread.

As you can see everything is "Faulted" meaning that an exception was thrown. Yet, still the application is proceeding merrily along the main thread

Finally, the enter key is pressed and the Task.WaitAll() method is called…. And the main thread only how has all those exceptions to contend with (in the form of an AggregateException)

Throw on WaitAll

That’s a bit of a gotcha if you don’t know where the AggregateException is coming from.

ASP.NET MVC – Pretty URLs

As the little Harris Benedict Calculator application stands, the only way to get some sort of answer out of it is to fill in the form. What if you wanted to pass someone a URL that takes them directly to the answer?

We could just create a controller action that takes the viewModel and have the MVC framework populate it from the URL. For example:

public ActionResult Result(HarrisBenedictViewModel viewModel)
{
    return Calculate(viewModel);
}

However, this would make the URL require a query string like this: http://localhost:42225/Main/Result?IsMale=True&Weight=75&Height=173&Age=37

This could be better.

Mapping a route for nicer URLs

What we can do is create a route to make the mapping nicer to look at than query string parameters. If we add it in before the default route it will be processed first if there is a match. So, the new RegisterRoutes method in the global.asax.cs file now looks like this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute("Permalink",
        "Gender/{Gender}/Weight/{Weight}/Height/{Height}/Age/{Age}",
        new { controller = "Main", action = "CalculateResult"}
        );

    routes.MapRoute(
        "Default",
        "{controller}/{action}",
        new { controller = "Main", action = "Calculate" }
    );
}

As you can see the new “Permalink” route defines a pattern that replaces parameters with properties from the view model. The controller’s action method takes in the view model that will have been populated with the values from the URL.

The controller’s action method is specified in the route as CalculateResult, and that method looks like this:

public ActionResult CalculateResult(HarrisBenedictViewModel viewModel, string gender)
{
    viewModel.IsMale = gender.ToLowerInvariant() == "male";

    return Calculate(viewModel);
}

There is actually on surprise here. Since we wanted a nice clean URL, the IsMale value is replaced with something more friendly looking. Since this isn’t in the view model, a new parameter on the action method is added to capture the value coming in from the URL. It is then processed so that the viewModel object is updated with the value that is needed.

Finally, the action calls another action, one that was created when we added our server side validation. This validates the view model and either returns the result, or if the view model is invalid directs the user to input the correct data. If the user has to fill in any data then the form will contain the values as provided in the URL and the validation messages will point out which bits need corrected.

Making a permalink on the results view

Now that we have everything set up to be able to pass around a URL with all the form values preset, it would be great to give people a way to get that link. So, on the CalculatorResults.cshtml file we are going to make that link using the HTML helper method ActionLink.

The snippet from the view looks like this:

<p>@Html.ActionLink("Calculate another?", "Calculate", "Main");
@Html.ActionLink("Permalink", "CalculateResult", new {
    Weight = Model.Weight,
    Height = Model.Height,
    Age = Model.Age,
    Gender = Model.IsMale ? "Male" : "Female" })</p>

The first action link is what was there before. The second is for the new permalink.

The first parameter is the text the user sees. The second parameter is the action method to use. When the routes are examined the first match is used, so the first route that can be determined to use the CalculateResult action method is the one we set up earlier. The third parameter is an anonymous type that provides the values to inject into the URL template provided in the RegisterRoutes method in the global.asax.cs file.

Now the user can get a permalink with nice URLs like this: http://localhost:42225/Gender/Male/Weight/75/Height/173/Age/37

Tidying things up a bit

Although we’ve got what we want, we are not going to leave things here. There is a little bit of tidying up to do first.

The action method is a little clunky. It essentially has to marshal values between the view model and the URL. The view model is a model of the view and the URL is just as valid a view as the HTML. If we can move that marshalling into the view model itself things would look better.

The HarrisBenedictViewModel class gets a new property that acts as a friendlier route to setting the IsMale property. The new property, called Gender, looks like this:

public string Gender
{
    get
    {
        return IsMale ? "Male" : "Female";
    }
    set
    {
        IsMale = (value.ToLowerInvariant() == "male");
    }
}

As a result, the action method on the controller no longer needs the extra parameter nor does it need the code to interpret that extra parameter. It now looks like this:

public ActionResult CalculateResult(HarrisBenedictViewModel viewModel)
{
    return Calculate(viewModel);
}

Finally, because the view model now contains a way to get the gender out (as well as in) the code in the cshtml file to generate the permalink can be cleaned up too. It now looks like this:

@Html.ActionLink("Permalink", "CalculateResult", new {
    Weight = Model.Weight,
    Height = Model.Height,
    Age = Model.Age,
    Gender = Model.Gender })

But why not…?

All the code in the cshtml file is doing is passing only bits of the view model to the ActionLink method, what’s wrong with just passing the whole view model. Surely it will just discard the bits it doesn’t need.

The problem is that it doesn’t know which bits it will need. If it finds properties on the view model that aren’t already in the URL template defined on the route, it will just add them as query string parameters, which makes the URL look like this:http://localhost:42225/Gender/Male/Weight/80/Height/173/Age/35?IsMale=True&BasalMetabolicRate=0&LifestyleRates=System.Collections.Generic.List%601[System.Collections.Generic.KeyValuePair%602[System.String%2CSystem.Int32]]

That list on the view model looks really ugly in the URL (and it doesn’t actually mean anything useful either).

Summary

In this post we made a new route to provide pretty URLs in order to access the resource that we needed in a permanent fashion without having to fill in the form or craft an HTTP Post. Then we tidied up the code a little in order to keep things a little cleaner.

You can download the sample code if you want to have a further play with it.

Other posts in this series

ASP.NET MVC – Server Side Validation

So far, we’ve built up a basic application and got some client side validation working. However, client side validation only goes so far. While it can prevent unnecessary trips to the server, it doesn’t prevent invalid data getting to the  server if JavaScript is turned off or if a user crafts a specific HTTP request to by pass validation.

Server side validation is quite easy, especially as we already have all the attributes attached to the view model from setting up the client side validation. The Controller class upon which our controller derives has a property called ModelState on which you can call IsValid. If true everything is okay and you can proceed. If not you need to get the user to correct the input.

The action method on the controller could change easily to something like this:

[HttpPost]
public ActionResult CalculatorResult(HarrisBenedictViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        CalculateAnswer(viewModel);
        return View(viewModel);
    }

    return RedirectToAction("CalculatorInput", viewModel);
}

Note that I’ve also refactored out the calculation to a method called CalculateAnswer.

However compelling this looks, the result is a bit of a mess. If the validation fails then it redirects back to the CalculatorInput controller action via a HTTP Status 302, which causes the browser to load the URL its been given. This URL now looks something like this: http://localhost:42225/?IsMale=True&Weight=45&Height=255&Age=16&BasalMetabolicRate=0&LifestyleRates=System.Collections.Generic.List%601[System.Collections.Generic.KeyValuePair%602[System.String%2CSystem.Int32]]

Bleurgh!

Let’s look at refactoring things slightly.

Refactoring to improve server side validation

First, we want the result to come back to the same controller action (well, almost the same action) as we started with.  Also, the action name was not very well named to begin with. It is an action, however the current name is a noun phrase. Actions should be verbs (or verb phrases).

The Controller class is refactored like this:

public class MainController : Controller
{
    public ActionResult Calculate()
    {
        HarrisBenedictViewModel viewModel = new HarrisBenedictViewModel();
        return View("CalculatorInput", viewModel);
    }

    [HttpPost]
    public ActionResult Calculate(HarrisBenedictViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            CalculateAnswer(viewModel);
            return View("CalculatorResult", viewModel);
        }

        return View("CalculatorInput", viewModel);
    }

    private static void CalculateAnswer(HarrisBenedictViewModel viewModel)
    {
        double bmr = 0; // Base Metabolic Rate
        if (viewModel.IsMale)
        {
            bmr =
                66 +
                (13.7 * viewModel.Weight) +
                (5 * viewModel.Height) -
                (6.76 * viewModel.Age);
        }
        else
        {
            bmr =
                655 +
                (9.6 * viewModel.Weight) +
                (1.8 * viewModel.Height) -
                (4.7 * viewModel.Age);
        }

        viewModel.LifestyleRates.Clear();
        viewModel.LifestyleRates.Add(
            new KeyValuePair<string, int>("Sedentry", (int)(bmr * 1.2)));
        viewModel.LifestyleRates.Add(
            new KeyValuePair<string, int>("Lightly Active", (int)(bmr * 1.375)));
        viewModel.LifestyleRates.Add(
            new KeyValuePair<string, int>("Moderately Active", (int)(bmr * 1.55)));
        viewModel.LifestyleRates.Add(
            new KeyValuePair<string, int>("Very Active", (int)(bmr * 1.725)));
        viewModel.LifestyleRates.Add(
            new KeyValuePair<string, int>("Extra Active", (int)(bmr * 1.9)));
    }
}

Because the View names no longer match the name of the action then they have to be named explicitly. The URLs are based on the routing information set up in the Global.asax.cs file

Because we updated the controller action name, and we want that to be the default for the route we need to update the routes:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}", // URL with parameters
        new { controller = "Main", action = "Calculate" } // Parameter defaults
    );
}

Now everything is set up to go.

When the application is run the path element of URL in the address bar remains at “/” and there is no query string. The output is much cleaner.

Summary

In this post the validation was refactored to better support server side validation and ensure that the URLs are kept clean.

The code is available for download if you want a play with it.

ASP.NET MVC 3 – Introduction to validation

In my previous post on MVC 3 I started a project to calculate a calorific intake required to maintain a stable weight. In this post I’ll extent that to add some validation to the inputs.

At the moment, since there is no validation, the use can just submit the input as it is with the default values. This produces this not so useful result:

1 - Result without validation

ASP.NET MVC 3 introduces unobtrusive client validation. It uses the data attributes available in HTML5 to store bits of data about the validation so that it can work more effectively and cleanly. If you want to enable unobtrusive client validation you need to add the following to the appSettings section in the web.config file:

<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

Since our project is brand new (not being upgraded from a previous version of ASP.NET) then the appSettings is already there. It is also possible to enable or disable this for individual views.

You also need to add the following to the <head> section of the _Layout.chhtml file:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

At this point we need to attribute the view model so that it knows what validation rules to put in place. The view model class file needs an additional using statement:

using System.ComponentModel.DataAnnotations;

Then each property can be attributed appropriately. The model is updated to look like this:

public class HarrisBenedictViewModel
{
    public HarrisBenedictViewModel()
    {
        LifestyleRates = new List<KeyValuePair<string, int>>();
    }

    public bool IsMale { get; set; }

    [Required(ErrorMessage = "Weight is required.")]
    [Range(50, 500, ErrorMessage = "Weight must be between {1}kg and {2}kg.")]
    public double Weight { get; set; }

    [Required(ErrorMessage = "Height is required.")]
    [Range(100, 250, ErrorMessage = "Height must be between {1}cm and {2}cm.")]
    public double Height { get; set; }

    [Required(ErrorMessage = "Age is required.")]
    [Range(18, 100, ErrorMessage = "Age must be between {1} and {2} years old.")]
    public int Age { get; set; }

    public double BasalMetabolicRate { get; set; }
    public IList<KeyValuePair<string, int>> LifestyleRates { get; set; }
}

As can be seen Validators can take string formatting placeholders so that if the data for the validation the message automatically updates to match, helping with the DRY principle.

The view also needs to be updated in order that the error messages are output when the user puts in incorrect data.

In the previous post, the fields in the input view looked like this:

<div class="editor-label">Height (in centimetres) </div>
<div class="editor-field">
    <input type="text" name="Height" value="@Model.Height" />
</div>

However, now we have to start using Html.EditorFor and Html.ValidationMessageFor as the validation feature adds a lot of data-* attributes to the elements in order to work.

If we change the .cshtml file to use the HTML Helper methods it looks like this:

<div class="editor-label">Height (in centimetres)</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Height)
    @Html.ValidationMessageFor(model => model.Height)
</div>

And the rendered output looks a little like this (modified slightly to word-wrap on to this blog):

<div class="editor-label">Height (in centimetres)</div>
<div class="editor-field">
    <input class="text-box single-line" data-val="true"
        data-val-number="The field Height must be a number."
        data-val-range="Height must be between 100cm and 250cm." data-val-range-max="250"
        data-val-range-min="100"
        data-val-required="Height is required." id="Height" name="Height"
        type="text" value="0" />
    <span class="field-validation-valid" data-valmsg-for="Height"
        data-valmsg-replace="true"></span>
</div>

Now if the application is run up then the validation kicks in when the submit button is pressed and the user is presented with messages telling them what needs fixed in order to submit the form

2 - Result with validation

Summary

In this post I’ve introduced the concept of unobtrusive client side validation. It should be stressed that if JavaScript is disabled on the browser then validation does not take place. By the same token, if a user crafts an HTTP Post request to the server, the validation will not have taken place either.

You can download the source code if you want to have a play with it.

Starting an ASP.NET MVC 3 application

In this post, I’m going to show the basics of starting an application with ASP.NET MVC 3. The demo application will be a simple calorie counter that takes in a number of values from the user that is then used to calculate the calorific intake. The original calculation can be found here here: How many calories should I be eating?

First, if you don’t have it already, you’ll need to download ASP.NET MVC 3. Remember to shut down Visual Studio 2010 for the installation. And if you don’t have it already, I’d also recommend downloading Visual Studio 2010 SP1 and upgrading to it.

Creating the project

In Visual Studio 2010, from the New Project Dialog, go to the Visual C#/Web templates section and select ASP.NET MVC 3 Web Application from the list in the middle. If you don’t see it, ensure that the drop down says .NET Framework 4.

For this project, the Name will be set to “HarrisBenedictCalculator” as that is the type of calculation that the application will be performing.

1 - Visual Studio 2010 New Project dialog

Once the appropriate details are entered the OK button takes you to a more specific dialog for ASP.NET MVC 3 projects.

Since I want to show everything rather than rely on existing templates where some of the ground work is already done, I’m selecting the Empty template. I’m also going to select the “Use HTML5 semantic markup” and set the view engine to Razor.

Because we are selecting the empty template, unit tests project creation is not available. We can do that later.

2 - New ASP.NET MVC 3 Project dialog

When the second dialog is OK’ed the project will be created. For all that I selected “Empty” Visual Studio has created an awful lot of files already.

What’s already in this “empty” project?

3 - What's in the empty ASP.NET MVC 3 project

The project contains a set of predefined folders, some of which are already populated with files.

  • Content: Contains static content files such as CSS, graphics and javascript files.
  • Scripts: Contains a profusion of javascript files.
  • Views:  This contains some files that act like Master files for the Razor engine, an error page Razor template and a web.config.

The top level folder also contains a global.asax file which defines a set of default routes and filters, a packages.config file which is used by NuGet and a set of web.config files.

If you attempt to run the application as is then it will compile, but you go directly to a error message that says “The resource cannot be found” because there are not controllers as yet, so the routing engine cannot find a route for the default resource.

4 - Resource Not Found

For the moment, we are going to have a simple static HTML page for the error. To that end the web.config will have the following added to it:

<customErrors mode="RemoteOnly" defaultRedirect="Error.htm" />

We will see error messages, but once deployed the end users won’t. If you want to learn more about error handling see this other post on custom error handling in ASP.NET MVC 3.

Creating the initial view and controller

First up we are going to create the model of the view, the ViewModel if you like. This will contains all the variables needed to generate the request and receive data back in the response.

public class HarrisBenedictViewModel
{
    public HarrisBenedictViewModel()
    {
        LifestyleRates = new List<KeyValuePair>();
    }

    public bool IsMale { get; set; }
    public double Weight { get; set; }
    public double Height { get; set; }
    public int Age { get; set; }
    public double BasalMetabolicRate { get; set; }
    public IList<KeyValuePair<string, int>> LifestyleRates { get; set; }
}

Incidentally, I always initialise lists so that I don’t have to do a null check. Normally most code will loop over the list, an empty list will loop the same number of times as a list that isn’t there.

Now, we are ready to create the controller. When you right click on the Controllers folder in the project structure, you get an “Controller…” option in the "Add” sub-menu.

5 - Add Controller

For this, I’m going to create a controller called Main and leave it empty. That gives us a class called MainController that is derived from Controller.

The controller is going to have two actions (this is a very simple application), one called CalculatorInput which will simply return a view for accepting the values, and the other called CalculatorResult which will display the results of the calculation. Both views use the view model we created earlier.

The CalculatorInput method looks like this:

public ActionResult CalculatorInput()
{
    HarrisBenedictViewModel viewModel = new HarrisBenedictViewModel();
    return View(viewModel);
}

The empty view model will be populated by the user. If we want to pre-populate values on the view then we can do so by setting the appropriate values in the view model.

ASP.NET MVC uses naming conventions to find things. So, by default, the view will be in a folder named after the controller (in this case “Main”) and the view will be named after the controller action (in this case “CalculatorInput”).

To create the View, create the appropriate folder in the Views folder (if it doesn’t already exist) and then right click the folder you’ve just created and select Add->View…

A dialog appears that looks like this:

6 - Add View

@model HarrisBenedictCalculator.Models.HarrisBenedictViewModel

@{
    ViewBag.Title = "Harris Benedict Calculator";
}

<h2>Harris Benedict Calculator</h2>

@using(Html.BeginForm("CalculatorResult", "Main", FormMethod.Post)){
    <fieldset>
        <legend>Information about you</legend>

        <div class="editor-label">Are you male?</div>
        <div class="editor-field">@Html.CheckBox("IsMale", Model.IsMale)</div>


        <div class="editor-label">Weight (in kilos)</div>
        <div class="editor-field"><input name="Weight" value="@Model.Weight" /></div>

        <div class="editor-label">Height (in centimetres)</div>
        <div class="editor-field"><input name="Height" value="@Model.Height" /></div>

        <div class="editor-label">Age (in years)</div>
        <div class="editor-field"><input name="Age" value="@Model.Age" /></div>

        <div class="submit"><input type="submit" value="Calculate!" /></div>
    </fieldset>
}

The view sets up the form for getting the user inputs.

The Html.BeginForm defines where the form will be sent to once it is complete and how it will be sent. In this case, the form will be sent by and HTTP POST to the CalculatorResult method on the MainController class. I’ll talk more about what that does in the next section.

The form consists of a number of inputs which, by convention, have the same name as properties on the Model. If the model is pre-populated then the initial values will be used to populate the values in each of the input elements.

The CheckBox is a special case. Because of the way HTML works, if the checkbox is unchecked then nothing is returned. The MVC application then does not know if the checkbox was not ticked, or if the checkbox simply didn’t exist at all. This may be an important distinction. Therefore an Html helper method is available that outputs the checkbox and an hidden field to go with it.

At this point we can run the application and get the initial view being displayed to us:

7 - Rendering first view

Submitting the answers

As I mentioned above, the Html.BeginForm helper method tells ASP.NET MVC what controller and method to return the result to when the user presses the submit button. So, we have to create a method to process that on the specified controller (in this case Main)

The Main.CalculatorResult method looks like this:

[HttpPost]
public ActionResult CalculatorResult(HarrisBenedictViewModel viewModel)
{
    double bmr = 0; // Base Metabolic Rate
    if (viewModel.IsMale)
    {
        bmr =
            66 +
            (13.7 * viewModel.Weight) +
            (5 * viewModel.Height) -
            (6.76 * viewModel.Age);
    }
    else
    {
        bmr =
            655 +
            (9.6 * viewModel.Weight) +
            (1.8 * viewModel.Height) -
            (4.7 * viewModel.Age);
    }

    viewModel.LifestyleRates.Clear();
    viewModel.LifestyleRates.Add(
        new KeyValuePair<string, int>("Sedentry", (int)(bmr * 1.2)));
    viewModel.LifestyleRates.Add(
        new KeyValuePair<string, int>("Lightly Active", (int)(bmr * 1.375)));
    viewModel.LifestyleRates.Add(
        new KeyValuePair<string, int>("Moderately Active", (int)(bmr * 1.55)));
    viewModel.LifestyleRates.Add(
        new KeyValuePair<string, int>("Very Active", (int)(bmr * 1.725)));
    viewModel.LifestyleRates.Add(
        new KeyValuePair<string, int>("Extra Active", (int)(bmr * 1.9)));

    return View(viewModel);
}

The above performs the calculation. The code may look a bit long, but the calculation is relatively simple. In a full business application this code would be separated out elsewhere.

The method is decorated with the HttpPost attribute which tells MVC that the method may only be called in response to an HTTP POST verb. The method also takes the view model class as a parameter. MVC will may the form inputs to the view model class as best it can. You can also specify a list of more primitive types (like int, string, double, etc.) that map to the input elements on the form.

The method itself performs the calculation then updates some items in the view model with the results of the calculation. The View is then returned with the view model.

The convention is that, unless specified otherwise, the view returned will be named after the controller method in a folder named after the controller class. So the view is in the ~ViewsMain folder in a file called CalculatorResult.cshtml

@model HarrisBenedictCalculator.Models.HarrisBenedictViewModel

@{
    ViewBag.Title = "Harris Benedict Calculator Result";
}

<h2>Result</h2>

<p>For a <em>@(Model.IsMale ? "man" : "woman")</em> aged <em>@Model.Age</em> years old,
weighing <em>@Model.Weight.ToString("0.0")</em> kg, and <em>@Model.Height</em> cm tall
should be taking in the following calories per day:
</p>

<div class="result">
@foreach (var lifestyle in Model.LifestyleRates)
{
    <div class="result-line">
        <span class="result-label">@lifestyle.Key</span>@lifestyle.Value Calories
    </div>
}
</div>

<p>@Html.ActionLink("Calculate another?", "CalculatorInput", "Main")</p>

This view extracts the data from the view model and renders it to the browser.

So, the answer I get looks like this:

8 - Final Result

The Razor syntax is quite easy to follow for the most part. Anything starting with an @ sign indicates the start of some C# code. The rendering engine is clever enough to detect HTML code and revert back when needed.

At the bottom of the page the HTML helper method ActionLink generates the URL to take the user back round to the start of the process again in case they want to calculate another set of calorie intakes.

Summary

In this post I’ve demonstrated some very basic initial steps to get going with ASP.NET MVC 3.

You can also download the sample code in order to have a play yourself.

Feedback from my DDD Scotland Talk on Parallisation

DDD Scotland 2011 Talk Opening SlideI got my feedback from my DDD Scotland 2011 talk on Parallelisation. I was actually pleasantly surprised. I guess I was being a little too self critical and the talk went over a lot better than I thought it had.

Some of the highlights:

  • Good clear samples and demos.
  • Enthusiastic speaker who really knew his stuff. Great talk!
  • Nice easy to understand examples. Getting the concepts across without clutter.
  • Useful info. Genuinely learnt something new.

And of course my favourite comment (despite being somewhat irrelevant, or should that be irreverent): Colin’s funky hair.

There were a couple of points that I need to address in future versions of the talk.

I only gave an overview of locking and the only demo that went close was the ConcurrentDictionary example in which all the locking mechanisms are internal to the ConcurrentDictionary. One person wanted more detail on locking so I shall endeavour to add a little extra into the presentation for DDD South West on locking including, if time allows, a specific demo.

The aspect of locking I need to address, is that I talked about when I used a semaphore in a project to restrict access to a scarce resource, but again I didn’t elaborate on it and another person would have found an example of a semaphore being used useful. I have already written about semaphores in a previous blog post, so I shall try and work that in to the next version of the presentation.

The other part is that the intro appears to be a little long and I need to shorten than slightly. If I can do that, it will at least free up space in a one hour talk to add the additional information on locking in later on.

I really appreciate the additional few moments people took at the end of my talk to write specifically what they enjoyed and what they disliked about my presentation, especially as lunch was waiting for them. It really gives me something to work with in order to improve the talk.

DDD Scotland Parallelisation Talk Overview

DDD Scotland 2011 Talk Opening Slide

Follow Up

I was asked a question during the talk I wasn’t immediately able to answer which I’ve now found the definite answer. What happens to parallel tasks running in the background when the application exits?

Examples

Here are all the examples from Saturday’s introductory talk on Parallelisation at DDD Scotland 2011.

Slide Deck

The slide deck is also available as a PDF file (3.0 Mb)

Background tasks and application exit

During my talk on Parallelisation at DDD Scotland 2011 I was asked what happens if the application finishes while there were still tasks running.

At the time, I was showing the Tasks Within Tasks demo and I showed what happened when the Wait call was removed in the Main method. Since the Wait call was removed the lines following it were immediately executed. Those were: to output that the program was ending; and to wait for a key press (to give the audience time to read the console output).

So, what happens when the application naturally concludes like when the Main method completes? When preparing the talk that question had simply not occurred to me. Do the background tasks continue until completion or do they all stop? I suspected they would just stop.

During the talk I simply removed the Console.ReadLine call, but then the console window appeared and then disappeared in a tiny fraction of a second. Did the tasks stop? Or, did the tasks simply continue without a console window available?

Since a further investigation at the time would have disrupted the talk I said I’d investigate further and follow up on my blog. So, this is that follow up.

I’ve now created a new example where the tasks output to files rather than the console. If the tasks stop, the files either won’t be created or contain incomplete output. If they are allowed to continue then the files will be complete.

Here is the code:

class Program
{
    private static readonly string folderName = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");

    static void Main(string[] args)
    {
        // Create a directory for the output to go.
        Directory.CreateDirectory(folderName);

        // Start the tasks
        for (int i = 0; i < 20; i++)
            Task.Factory.StartNew(PerformTask, TaskCreationOptions.AttachedToParent);

        // Give the tasks a chance to start something.
        Thread.Sleep(750);
    }

    public static void PerformTask()
    {
        // Create a new file in the output directory
        string path = folderName + "\" + Task.CurrentId + ".txt";
        using (StreamWriter writer = File.CreateText(path))
        {
            // Ensures that all write operations are immediately flushed to disk
            writer.AutoFlush = true;

            // Write stuff to the file over a period of time
            writer.WriteLine("Starting Task {0}", Task.CurrentId);
            Thread.Sleep(500);
            writer.WriteLine("Ending Task {0}", Task.CurrentId);
        }
    }
}

In the Main method, the Sleep waits long enough that the first few tasks will run to completion and further queued tasks are started.

The result on my machine is that the first 4 tasks run to completion, the next 4 tasks are in still being processed when the Main method naturally concludes. At this point the application exits. All the running tasks are forced to exit leaving files with only the first part of their content in them.

So, in answer to the question I was asked: If the application finishes while there are tasks still running then all the running tasks are all stopped without being allowed to complete. No more queued tasks are started.

Custom error pages and error handling in ASP.NET MVC 3

In ASP.NET MVC 3 a new bit of code appeared in the global.asax.cs file:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
}

The above method is called from the Application_Start() method.

Out of the box, what this does is set up a global filter for handling errors. You can still attribute controller methods or classes as before, but now, if you don’t have a specific HandleErrorAttribute attached to the controller method or class then the global one will take over and be processed.

However, you are not going to get custom errors just yet. If you have a bit of code that causes an exception to be thrown that is not caught then you will just end up with the Yellow Screen of Death as before. For example, this code:

public class HomeController : Controller
{
    // ...

    public ActionResult About()
    {
        throw new Exception("This is not good. Something bad happened.");
    }
}

Will produce this error

Error Handling - Without Custom Error

The missing part of the puzzle is to turn on Custom Errors. This happens in the web.config file. There are three basic options for the mode: “Off” which will show the YSOD to everyone, “RemoteOnly” which shows the YSOD on the local machine (the web server) and the custom error to everyone else, and “On” which shows the custom error to everyone including the local machine.

For development purposes I tend to leave it set to “RemoteOnly” so that I get the YSOD and I get to see what the error is, yet everyone else gets the custom error. However, for developing the actual custom errors themselves we’ll need to set the mode to “On” so we, as developers, get to see the error.

<system.web>
  <customErrors mode="On" defaultRedirect=”~/BadError.htm"/>
</system.web>

The defaultRedirect does not go to a controller action, it is set to a static HTML page that will be displayed if all else goes wrong. This is a final backstop to ensure that the user at least will see something nice event if the error page itself has some issues.

Normally, the error will show the ~/Views/Shared/Error.cshtml view. However, since the view can throw an exception itself there ought to be a backstop custom error page.

The HandleErrorAttribute defaults to using the view "Error" which will display shared view ~/Views/Shared/Error.cshtml.

You can change that by setting the view property on the HandleErrorAttrubute, like this:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute {View = "MyCustomError"});
}

I’ve set my error view to display the details of the exception for the purposes of this demo.

@model System.Web.Mvc.HandleErrorInfo

@{
    ViewBag.Title = "Error";
}

<h2>
    Sorry, an error occurred while processing your request.
</h2>
<p>Controller = @Model.ControllerName</p>
<p>Action = @Model.ActionName</p>
<p>Message = @Model.Exception.Message</p>
<p>StackTrace :</p>
<pre>@Model.Exception.StackTrace</pre>

NOTE: In normal production code you would never expose the details of the exception like this. It represents a considerable security risk and a potential attacker could use the information to gain valuable information about your system in order to construct an attack against it.

Now, if we re-run the same application and go to the About page (handled by the HomeController’s About action) then we will get our custom error page.

Performing additional actions on an exception

Overriding OnException in a Controller

If you want to perform additional actions, rather than just simply show a custom error page, then you can override the OnException method from the Controller class on your own controller derived class. If you want to do this for all controllers then  you may want to create a common base controller that all your controllers inherit from. For example:

public class CommonController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        // Do additional things like logging here.
        base.OnException(filterContext);
    }
}

Then in each of your controllers, inherit from this common controller like this:

public class HomeController : CommonController
{ ...

That will ensure that all your controller have the same functionality.

Creating a FilterAttribute

You could alternatively create a FilterAttribute. This can provide benefits of providing global functionality if you add it to the global filter collection, or very fine grained functionality if you need it on a few sparse controller actions by adding it as an attribute on the controller action.

The filter may look like this:

public class LogExceptionFilterAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        // Log the exception here with your logging framework of choice.
    }
}

If you want to have the filter applied to all controller actions, you can set it up in the RegisterGlobalFilters method in the Global.asax.cs file like this:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new LogExceptionFilterAttribute());
    filters.Add(new HandleErrorAttribute());
}

Or, if you prefer to have finer grained control you can decorate individual controller classes or controller actions with it, like this:

[LogExceptionFilter()]
public ActionResult About()
{
    throw new Exception("This is not good. Something bad happened.");
}

Tip of the Day #23: Getting going with IIS Express

First, if you don’t have it already you need to download IIS Express (you can also use this link to get the full install, not via Microsoft’s web installer, if you are behind a proxy that is preventing the installation). And, I’d also recommend downloading Visual Studio 2010 SP1 and upgrading to it.

In your web project, open up the properties by right clicking the project and selecting properties, or pressing Alt+Enter while the project is selected.

You will then be presented with a view like this:

1 Initial Web Properties

By default, in the servers section of the Web tab the “Use Visual Studio Development Server” (aka Cassini) will be selected. Change this to “Use Local IIS Web Server”

2 Change to Local IIS Web Server

If you want to customise the settings you may do so. I tend to set a specific local port so that I know that all my applications don’t class with one another and that I can easily identify it later. My naming scheme to select 4 or 5 digits that are derived from the name of the project as if dialled into a telephone keypad. (Some people think that’s a bit weird but it makes it easy to avoid port clashes and to reverse the port into the project if you ever get lost.)

If necessary you can define the virtual directory in the Project URL and configure it by pressing “Create Virtual Directory”.

3 Setting a Virtual Directory

If you don’t “Create Virtual Directory” and you attempt to run the project, you’ll get a warning dialog that asks if you want to configure it. If you select yes, then Visual Studio will configure the virtual directory for you and start the application.

4 Not configuring a Virtual Directory

Finally, if you need to see what Sites IIS Express is running there is a tray icon you can right click on to see.

5 System Tray Icon for IIS Express

And if you click “Show all applications” you get to see all the sites that IIS Express is running. Clicking on a URL takes you to that site, anywhere else on the line will bring up details of the site in the lower part of the dialog.

6 IIS Express Running Applications

Clicking on the “Parent” name will take you to the instance of Visual Studio that the application is running from. This is a really nifty feature to get you back to the correct instance of Visual Studio if you are running many of them at once.

Clicking on the “Path” will open up Windows Explorer to show you the folder in which the site is located. And clicking “Config” will open the config file in Visual Studio.