>

I'm currently playing around with Asp.Net MVC for a private little "pet-project" and I'm amazed how easy it is to make Ajax calls using jQuery!

I'm currently implementing the following story:

As a user I want to search for available rooms in order to make a reservation

So my web page would look something like this: (obviously I'm not a web designer:)

image

And when the user clicks the search button an Ajax call will be made to the server which returns a list of available rooms. After the call the page will look like this:

image

jQuery Code

The call is easily made with the jQuery $.getJSON - method. Lets look at the JavaScript that is executed when the user clicks the "search" - button

$("#btnSearch").click(function() {
//users room requirements
var roomRequriements = {
"requirements.From": $('#fromDate').attr("value"),
"requirements.To": $('#toDate').attr("value")
}

//clear table
$("#availableRooms tbody").html("");
$.getJSON(
"/Booking/FindRooms", roomRequriements, function(rooms) {
$.each(rooms,
function(i, room) {
var row = $("<tr/>").attr("id", room.Id);

$("<td/>").html(room.Type).appendTo(row);
$(
"<td/>").html(room.Description).appendTo(row);
$(
"<td/>").html(room.Price).appendTo(row);
$(
"<td/>").html($("<input type='radio'/>").attr("id","radio" + i)).appendTo(row);

$("#availableRooms tbody").append(row);
});
});

$("#availableRooms").trigger("update");
return false;
});

The first argument to getJSON is the URL that is going to get our call. If you are familiar with Asp.Net MVC you'll know that "/Booking/FindRooms" will be routed to the FindRooms - method on a class called BookingController.

The second is a map of key/value - pairs that will be sent as parameters to the server. The name of the keys is important because the entire map will be automatically mapped to an C# object by Asp.Net -MVC (more on this later).

The third is the callback that will execute when the call returns. As you see I'm iterating over some kind of magical object called "rooms" and for each "room" I'm adding a new row to my list of rooms that the user can choose from.

Where did that magical "rooms" object come from?

The "rooms" object is representing the returned data that our server sent in response to our call. In our case the server sent an IList<Room> serialized as JSON back to us. To explain this further we must look at the FindRooms method.

The Asp.Net MVC Code

So the user clicked the "Search"-button and a script in or browser took the entered dates and passed them as parameters to the URL /Booking/FindRooms. Asp.Net MVC received the call and routed it to a method on BookingController called FindRooms. Lets se how that method looks.

public ActionResult FindRooms(RoomRequirements requirements)
{
return Json(new List<Room>
{
new Room
{
Id
= 1,
Type
="Single",
Description
="201",
Price
= 1100.0
},
new Room
{
Id
= 2,
Type
="Single",
Description
="301",
Price
= 1000.0
}
});
}

Is that all??

Yes, and that's why I love Asp.Net MVC! ( you can write soooo clean code and the support for TDD is amazing!)

Remember those strange keys in the map that was sent as parameters? (requirements.From,requirements.To)

By using those keys Asp.Net MVC figured out how to deserialize that into the required "requirements"-parameter that our FindRooms -method expects. ("RoomRequirements" has two properties "To" and "From"). This means that we can keep our C#-code clean from "magic"-strings and let Asp.Net MVC get the parameters out of the request in a strongly typed manner. This is achieved be something behind the scenes called ModelBinders more on that here.

Data is returned back to the caller serialized in JSON by the Json method of the Controller (the MVC base-class for all controllers).

Ok, a list of Room-objects was sent back to the client in JSON-format. Can that explain those magical "rooms" and "room"-objects?

It sure can!! As you would guess the method getJSON is expecting JSON formatted data back from the call to the server. When this happens jQuery automatically deserialize's the data to corresponding Javascript objects. So "rooms" was serialized to a list of "room"-objects. We iterated the list using jQuery's $each -function and created our row using room.Type, room.Name etc.

Conclusion

jQuery and Asp.Net MVC helps us to write powerful and clean code with just a few lines. And as a bonus it helps us to keep our "magical - strings" usage low.

Hey, what about all that TDD - stuff you force us to do at work. Don't you do it on your hobby projects?

Of course I used TDD for this. (Yes, I should use QUnit to TDD the JavaScript, I'll do that next time , promise! :)

Lets see how we can test our controller action with just a few lines of test code:

[Test]
public void Find_avaliable_rooms()
{
var controller
= new BookingController();
DateTime to
= DateTime.Today;
DateTime from
= DateTime.Today.AddDays(1);

var model = controller.FindRooms(new RoomRequirements {From = from, To = to})
.AssertResultIs
<JsonResult>()
.AssertPayloadIs
<IList<Room>>();

Assert.That(model.Count, Is.EqualTo(2));
Assert.That(model[
0].Id, Is.EqualTo(1));
Assert.That(model[
0].Type, Is.EqualTo("Single"));
Assert.That(model[
0].Description, Is.EqualTo("201"));
Assert.That(model[
0].Price, Is.EqualTo(1100.0));

}

Asp.Net MVC is really easy to unit test. In the code above I just create my controller. Invoke the "FindRooms" - method and make sure it return a JsonResult in which the payload is a list of rooms.

Note: AssertResultIs is a method from MVCContribs TestHelpers and AssertPayloadIs is one of my own helpers.

Phew, long post, must sleep now....