MVC JsonResults - How To Call Them With JQuery

If you've ever tried to send data from a webpage up to a server or wanted to call a serverside method from a web page, you've probably encountered JsonResult methods in MVC.
Working with JsonResults can be a little tricky on your first try, but once you've done it a few times, it's a piece of cake.
In this article I'm going to describe the process of calling a JsonResult method from javascript code (Using JQuery) and show you how you can work with the response you get back.

What is a JsonResult?

A JsonResult is an MVC controller method result type, which implements ActionResult.
It is used to return a JSON formatted response, other than that, it's very much like any other MVC ActionResult method.

In your controller, you will need to crate a method, which returns a JsonResult, and optionally accepts one or more parameters.
You will also need to decide if you want your method to respond to GET or POST requests (I'll show you how to implement this later on in the article).

Create the JsonResult Method:

Start by creating a public JsonResult as below in your controller.
In the sample below, you can see that I've called the method "DoStuffString", which accepts a single parameter named "mytext".
Also note that I've decorated it with the [HttpGet] attribute, this mean that this method will only ever respond to GET requests.

    [HttpGet]
    public JsonResult DoStuffString(string mytext)
    {
    return Json("You said " + mytext, JsonRequestBehavior.AllowGet);
    }

Perform the AJAX Call To The JsonResult Using JQuery (GET)

Now that we've got the JsonResult constructed we can write some javascript using JQuery to call it.
In the below code sample I've place all of the code within a $(document).ready(function(){}); block.  This is partially habit, but it also ensures that click even handler will register properly (i.e. only attach the the button after the button has been created).
Create a button with an id of "myButton1" and a text input field with an id of "myText".

    <script type="text/javascript">
        $(document).ready(function () {
            $("#myButton1").click(function () {

                var textToSend = $("#myText").val();

                var url = "/Home/DoStuffString?mytext=" + textToSend;

                $.ajax({
                    url: url,
                    async: true,
                    dataType: "json",
                    type: "GET",
                    success: function (data) {
                        alert("success " + data);
                    },
                    error: function (data) {
                        alert("error " + data);
                    },
                    complete: function () {
                        alert("complete");
                    }
                });

            });
        });
    </script>

$.ajax() Options:

  • url:
    • The url variable is the address that your method will reside at.  In my example, I used the Home controller.
      If you look at the query string at the end of the url you will see "mytext", remember that this is the parameter name in the "DoStuffString()" JsonResult method, it's important that these match as it's what the MVC model binder will use to map the query string parameter to the ActionResult's parameter.
  • async:
    • This means that the request will execute asynchronously, i.e. it wont lock up the browser while waiting for a response.
      This defaults to true, but I've included it incase yuo want to make it a synchronous request.
      Generally, you should always keep this set to true unless you have a good reason not to.
  • dataType:
    • This is the data type you expect to recieve back as a response, we expect to recieve json back as we're calling a JsonResult method.
  • type:
    • This is the Http verb that you intend to use to make the request with. (In this first example, we want to use a GET as that's what our JsonResult method will respond to).
  • success, error and complete:
    • These 3 options are callbacks.
      success will fire when the request executes successfully.
      error will fire when the request fails for some reason.
      complete will always fire regardless of whether or not the request succeeded.  This callback is frequently used for cleanup of resources, such as perhaps removing a loading animation.

Results:

If you now open up your application, typing something into the textbox and press the button, you should recieve a successful response saying "success you said <insert your text here>", you will also get a "complete" alert.

Performing a POST Request

You've done a GET request, so now lets try the same thing again but with a POST.
The rules are a little different and requires a little more effort, but it's basically the same process.

Create a JsonResult Method:

    [HttpPost]
    public JsonResult DoStuffObject(Models.Person person)
    {
    return Json(person);
    }

This time create a JsonResult method called "DoStuffObject" and have accept a parameter of a Person object. We'll be populating this object's properties in javascript and the MVC model binder will it to the person parameter in the JsonResult.
Also note that I've decorated the method is [HttpPost], so this method will only ever respond to POST requests.
This method simply accepts the Person object as a parameter and returns it back to the calling code, nothing fancy going on here.

    public class Person
    {
        public string Forename { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }

Perform the AJAX Call To The JsonResult Using JQuery (POST)

    <script type="text/javascript">
        $("#myButton2").click(function () {

            var person = {
                Forename: "john",
                LastName: "smith",
                Age: 99
            };

            var url = "/Home/DoStuffObject";

            $.ajax({
                url: url,
                async: true,
                data: JSON.stringify(person),
                contentType: 'application/json; charset=utf-8',
                dataType: "json",
                type: "POST",
                success: function (data) {
                    alert("success " +
                    "\n Forename = " + data.Forename
                    + "\n lastname = " + data.LastName
                    + "\n Age = " + data.Age);
                },
                error: function (data) {
                    alert("error " + data);
                },
                complete: function () {
                    alert("complete");
                }
            });

        });
    </script>

Create another input button with an id of "myButton2".
The first thing I've done is create a Json object in javascript and assigned it to a variable called "person".  Again, this is important that it matches the parameter name of the JsonResult method in your controller, as it's what helps the model binder to accurately match the input you're giving it to the parameters of the method.

If you look at the url, you'll notice that there is no query string after the method name, that's because we're now performing a POST operation, when peforming a POST operation data goes in the body of the request rather than the request string.

I've added another option to the $.ajax() request, "data".
Simply assign the person variable to this option, wrapping it with JSON.stringify() (This converts the JSON object into a string).
I've also used the contentType option, this is because the default is "application/x-www-form-urlencoded; charset=UTF-8", and since we're sending a JSON string, we need to change this to explicitly declare that we're sending JSON.

The type option has also been updated with "POST" to reflect that we're performing a POST request and not a GET like the previous example.

The content of the "success" callback function looks a little different from our previous example.
We're now treating the "data" variable in the callback parameter as a JSON object with multiple properties.  In our previous example it was still a JSON object, but there were not additional properties for us to access, just the text that you returned.
This time, we've got the forename, lastname and age to work with.
As you can see, to access these properties you just need to use the "data" variable, ".propertyName", and you'll be able to access the property.

Working With A Collection From A JsonResult

So far we've discussed how to handle responses back from the server when only a single item (With or without multiple properties) is returned, however, how can you handle a collection of items comming back?

Create another JsonResult method that returns a list of Person objects, (the original, plus a newly created one).

    [HttpPost]
    public JsonResult DoStuffObjectCollection(Models.Person person)
    {
        List<Models.Person> people = new List<Models.Person>();
        people.Add(person);
        people.Add(new Models.Person() {Forename="bob",LastName="smith",Age=98 });
 
        return Json(people);
    }

Now change the "success" callback function in the javascript to use the JQuery .each() function (The equivalent of a "for each" loop).
You'll now get an alert for each of the Person objects that is returned from the JsonResult.

    <script type="text/javascript">
        $("#myButton3").click(function () {

            var person = {
                Forename: "john",
                LastName: "smith",
                Age: 99
            };

            var url = "/Home/DoStuffObjectCollection";

            $.ajax({
                url: url,
                async: true,
                data: JSON.stringify(person),
                contentType: 'application/json; charset=utf-8',
                dataType: "json",
                type: "POST",
                success: function (data) {

                    $.each(data, function (key, value) {
                        alert("success " +
                        "\n Forename = " + value.Forename
                        + "\n lastname = " + value.LastName
                        + "\n Age = " + value.Age);
                    });
                },
                error: function (data) {
                    alert("error " + data);
                },
                complete: function () {
                    alert("complete");
                }
            });
        });
    </script>

Get the GitHub repository

If you enjoyed this article, please consider giving it a +1

Tags: mvc, json, jsonresult, jquery, javascript, asp.net

Published: 5/12/2014 8:22:32 PM
By: Stephen Warren