JSON with ASP.NET MVC 4

As a newcomer to JavaScript and jQuery, I wanted to write a (supposedly) simple little web site which used JSON (JavaScript Object Notation) to transmit information from a database to a web page. Surprisingly there didn’t seem to be any self-contained example or tutorial (that I could find) that showed how to do this basic operation. So here is the result of my attempt. It turns out that it is actually quite simple, once you know what to do.

First off, what is JSON? It is an alternative to XML as a way of sending information from one device to another. It’s a subset of the notation that can be used in JavaScript to define an object literal, which we saw in the last post. As an example, we might have some information on the numbers of various titles of comic books that are stored in a database. After we’ve retrieved this data from the database, we can encode it into JSON, so that it looks like this:

[
  {"Title":"Batman","Count":1},
  {"Title":"Fantastic Four","Count":2},
  {"Title":"Spider-man","Count":2},
  {"Title":"Superman","Count":1},
  {"Title":"Thor","Count":2}
]

That is, the data are stored as name-value pairs. In this case, each element in the array is actually a compound object consisting of two name-value pairs (Title and Count). We could have a simple list of single name-value pairs, or we could have deeper nesting of objects. There are various restrictions on the syntax for JSON objects, but as we’ll see, in MVC 4 you won’t usually have to write your own JSON, since there is a library routine that does it for you.

Now that we know what JSON is, how do we use it as a mediator between a database and a web page in ASP.NET MVC 4? We’ve seen that the procedure for generating web pages in MVC is as follows.

  1. Write a controller that contains a method that is called when a client requests a web page from the server.
  2. Write a view that is linked to the controller method, and which generates the markup that is returned to the client.

The controller method will usually collect some data from some other source, such as a database or some other C# code (which is usually part of the Model in MVC). This data is then packaged up, possibly in a C# object, and sent to the View, where the View formats the data and generates the HTML which is interpreted by the browser.

The procedure for using JSON doesn’t quite fit this pattern. Basically what happens is this:

  1. Client requests a web page.
  2. Controller method is called to process this request.
  3. The corresponding View is returned to the browser.
  4. The View contains some JavaScript code that makes another request to the server, this time asking for some data in JSON format.
  5. different Controller method from that called in step 2 is called to generate the JSON, which is returned to the browser.
  6. The JavaScript code processes the JSON and generates some HTML which is displayed.

The key point is that the JSON is not meant to be displayed as raw data by the browser; rather, it is retrieved by the browser and then processed on the client side before it is displayed.

We’ll illustrate this by showing how the data above can be obtained from the database and sent to a web page using JSON. First, we’ll add a controller to our ComicShop project that we’ve been using to demostrate things:

using System.Web.Mvc;
using ComicShop.Models;
using System.Collections.Generic;

namespace ComicShop.Controllers
{
  public class JsonController : Controller
  {
    //
    // GET: /Json/

    public ActionResult Index()
    {
      return View();
    }

    private IComicRepository comicRepository;

    public JsonController()
    {
      comicRepository = new ComicRepository();
    }

    public JsonController(IComicRepository comicRepository)
    {
      this.comicRepository = comicRepository;
    }

    public ViewResult JsonSummary()
    {
      return View();
    }

    public ActionResult Summary()
    {
      IEnumerable<ComicSummary> summaries = comicRepository.GetSummaries();
      return Json(summaries, JsonRequestBehavior.AllowGet);
    }

  }
}

This controller uses the IComicRepository interface and ComicRepository class that we introduced earlier. This controller contains two methods of interest here. The one called JsonSummary() simply returns a View, which is the View that requests the JSON data (we’ll get to this View in a moment).

The Summary() method is the one that produces the JSON data. The first line in this method requests the data from the database (see the earlier post for details of how this is done; all that’s important here is that we do get this data). The data is returned as an IEnumerable<ComicSummary> list. The ComicSummary class is defined as:

namespace ComicShop.Models
{
  public class ComicSummary
  {
    public string Title { get; set; }
    public int Count { get; set; }
  }
}

That is, it contains two data fields named Title and Count.

The second line in Summary() calls the library method Json() to create the JSON data. It is passed the list of ComicSummary objects in the variable summaries. The second parameter allows Summary() to provide JSON data in response to an HTTP Get request (by default, such a response is blocked for security reasons, so this parameter is needed). This returns the JSON string we gave above.

That’s all there is to producing JSON data (as promised, you didn’t have to actually write any raw JSON yourself, since the Json() method does it for you). If you want to verify that Summary() actually works, you can call it directly from a web browser by using the URL http://localhost:36195/Json/Summary (the port number for your localhost server will probably be different; what’s important is the path /Json/Summary), and you should see the raw JSON data printed in the browser.

Note that we did not associate a View with the Summary() controller method. As far as the browser is concerned, it is receiving raw text as a response to its request to Summary, so it just displays that. We need to do something special if we want it to interpret the JSON as data and incorporate it into a ‘real’ web page.

To that end, we turn our attention to the JsonSummary() controller method, and have a look at its View. This is in the file JsonSummary.cshtml:

<h2>JsonSummary</h2>
<script>
    $.getJSON('/Json/Summary',  function (data) {
        var items = [];
        $.each(data, function (key, val) {
            items.push('<li>' + key + ': ' + val.Title + ' (' + val.Count + ')</li>');
        });

        $('<ul/>', {
            html: items.join('')
        }).appendTo('body');
    });
</script>

As you can see, most of this file is JavaScript. However, it’s not all primitive JavaScript; it makes use of jQuery, so you need to make sure your web project has jQuery installed. If you started with an Empty project, you’ll need to do this yourself; if you started with a full Internet project, it will already be included.

To add in jQuery, right-click on the Solution in SolutionExplorer and select Manage NuGet Packages. Search in the Online section and find jQuery, then click Install. JSON should already be installed – you can check this by opening up References in SolutionExplorer and seeing that Newtonsoft.Json  is included in the list.

NuGet should take care of installing these packages and should find some jQuery JavaScript files in your Scripts folder (if you didn’t have a Scripts folder, it will be created by the installation).

We’re not quite done yet, though. In order for jQuery to be used in your View, that View needs to run the jQuery script. You could include a <script> tag in the View file itself, but if you plan on using jQuery in a lot of Views, it makes more sense to put it in the common layout file which we considered earlier. This file is called _Layout.cshtml and is in the Shared folder within the Views folder. Add the call to the jquery script in the <head> section of the layout. The modified _Layout.cshtml file looks like this:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <script src="~/Scripts/jquery-1.8.2.js"></script>
    <meta name="viewport" content="width=device-width" />
    <title>Comics</title>
</head>
<body>
    <h2>Comic Shop</h2>
    <div>
        @RenderBody()
    </div>
</body>
</html>

The call to the script is on line 9. The actual version number of jquery may differ from 1.8.2 if you install it later on, but just insert whatever version you got from NuGet.

That’s all we need to get the JavaScript to run, but there’s one more thing that’s very useful, and that’s to get Intellisense working for jQuery. Complete instructions for doing this are here, provided you’re using VS 2012. My _references.js file looks like this:

/// <reference path="jquery-1.8.2.intellisense.js" />
/// <reference path="jquery-1.8.2.js" />

Right, now we can look (finally) at JsonSummary.cshtml. A lot of the code there relies on a knowledge of JavaScript and jQuery syntax, so I won’t go through it in detail. However, I’ll mention a few key points so you can adapt it for your own purposes.

First, the $.getJSON() call is a jQuery method which makes a request to the URL given as its first argument for some JSON data. In our case, we use a relative URL /Json/Summary (the leading / is important: don’t leave it out!). If this call is successful, the JavaScript function given as the second argument to $.getJSON is called. (If the call fails, this function isn’t called, and you’ll get nothing on your web page apart from the HTML that is outside the <script> tag. This can make debugging a nightmare, since you won’t know what’s wrong, but never mind.)

The argument ‘data’ sent to this function is the JSON code. This function then constructs an array called ‘items’ by iterating through ‘data’ using the jQuery $.each() method. The second argument to $.each() is another function, this time taking two arguments. The ‘key’ argument is the integer index of the element from ‘data’ that is being processed, and ‘val’ is that actual element from ‘data’. Remember from the JSON above that each element in ‘data’ is a compound object of type ComicSummary, so it contains a Title and a Count field. We access these fields to create a HTML list entry on line 6, and push this onto the items array.

The last bit of code on lines 9 to 11 creates a <ul> tag and adds the items list to it, then it adds the <ul> tag to the body of the page. The final result looks like this:

About these ads
Post a comment or leave a trackback: Trackback URL.

Comments

Trackbacks

  • By jQuery: simple selections « Programming tutorials on November 6, 2012 at 5:35 PM

    [...] This assumes that you’ve got your CSS file in Content/jQueryDemo.css and that the jquery library is in Scripts/jquery-1.8.2.js. If you have a different version of jQuery or put your files in different places, you’ll need to modify those 2 lines in the header. If you’re using Visual Studio,  you can include jQuery as described in the last post. [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 38 other followers

%d bloggers like this: