Ajax with JQuery and MVC

I recently had to explain to a colleague how to do Ajax with JQuery and ASP.NET MVC.  I thought I might put my example here for future reference.

I’m first going to take a look at the basics of loading and using data with Ajax within the MVC framework and in a following post I will take a look at some of the more advanced features like posting a form with Ajax.

Example Time

For my example I have created a simple page to display widgets.  Each widget has a list of attributes and comments which we will load (via Ajax) when the widget is selected.  (As you can see – styling is not really my thing.)

Website

The nice thing about working with Ajax within MVC is that we can call the controller directly – this means that the Ajax methods on the server look pretty similar to regular actions and can be Unit-Tested in exactly the same way.  Here are the methods I created for loading the details and comments for the selected widget.

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult WidgetDetails(string widgetId)
{
    var widget = widgetService.GetWidgets().WithId(Int32.Parse(widgetId));

    return Json(widget.Details);
}

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult WidgetComments(string widgetId)
{
    var widget = widgetService.GetWidgets().WithId(Int32.Parse(widgetId));

    return Json(widget.Comments);
}

MVC will automagically convert the .NET objects I am returning (IList and IList in this case) to Json which can be consumed by JavaScript.  These 2 methods are actually all we need on the server.

JQuery Ajax

The syntax for using Ajax with JQuery is very simple and best illustrated with an example.  Here I am calling the WidgetDetails action on the Example controller.

jQuery.ajax({
    type: "GET",
    url: rootPath + "Example/WidgetDetails",
    data: "widgetId=" + selectedWidgetId,
    dataType: 'json',
    success: function(result) {
        jQuery.each(result, function(i, val) {
            $("#widgetDetails").append("<li>" + val.Attribute + " - " + val.Value + "</li>");
        });
    }
});

Which is really very simple.

But wait – there’s more

If you are an incredibly observant reader you might have noticed that I magically used the ‘rootPath’ variable to specify the complete URL for my action.  If we were writing this code inside a view we could use the Url object to create the URL for us using the following syntax.

<%=Url.Action("WidgetDetails", "Example") %>

While this would work it’s not the most elegant solution – you probably want to move all your JavaScript into separate files and mixing generated code with JavaScript can get pretty messy.

So to get around this issue I simply declare a variable called ‘rootPath’ in the master page and set it to the root of my website.

<%="<script type=\"text/javascript\">var rootPath = '" + Url.Content("~/") + "';</script>" %>

I have never actually seen this technique being used anywhere else, so if you know of a better way please let me know.

Happy coding.