jQuery AJAX (and the shorthands)

Using AJAX (asynchronous JavaScript and XML) for your ASP.NET MVC application is made relatively easy using the jQuery .ajax method or one of the shorthand methods available. I found a nice introduction on jQuery Fundamentals which explains the concepts i used as the basis for my own experiments with MVC5 and AJAX.

$.ajax: basic usage

The $.ajax method takes a configuration object specifying things like the url, the http-verb to use, the format, and the callback functions for the succes and error situations. A straightforward way to render this is like this:

@section Scripts {
    <script type="text/javascript">

        function addFav()
        {
            $.ajax({
                url: '@Url.Action("AddFavorite", "Test", new { id = Model.Id })',
                type: 'POST',
                dataType: 'json',
                success: function (resp) {
                    $('#notificationBox').html(resp);
                },
                error: function (jqXHR, status, err) {
                    errMsg = jQuery.parseJSON(jqXHR.responseText);
                    console.log('Oops: ', status, errMsg);
                }
            });
        }

        $(function () {
            $('#favMe').on('click', addFav);
        });

    </script>
}

Somewhere on the page, there is an element with id ‘favMe’ and another element with id ‘notificationBox’. This code will fire the addFav method when the user clicks the element with id ‘favME’. When the ajax call succeeds the message that is returned from the server is written to the ‘notificationBox’ element.

The server side code looks like this:

[HttpPost]
public JsonResult AddFavorite(int id)
{
         if (!User.Identity.IsAuthenticated)
         {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json("You must be logged in to add a favorite!");
         }

         var fav = new Favorite(){UserName = User.Identity.Name, Id = id};

         // ... validate id and persist changes ...

         return Json("Added to favorites", JsonRequestBehavior.AllowGet);
}

Returning a http statuscode like 400 (Bad Request) or 500 (Internal Server Error) will effect in the error callback being called on the client side. Just throwing an exception from the action method will send an internal server error back to the client. By specifying the http statuscode yourself you have more control over the data being returned to the client. One note though: a statuscode of 401 (unauthorized) does not result in the error callback being called. Instead, the success callback is called.

Shorthand Methods

jQuery has a number of shorthand methods for the $.ajax method that can result in less javaScript code:

jQuery.get() loads data from the server using a HTTP GET request.
jQuery.post() loads data from the server using a HTTP POST request. The above code could also be written using the post method:
function addFav() {
     $.post('@Url.Action("AddFavorite", "Test", new { id = Model.Id })',
                function (resp) {
                    $('#notificationBox').html(resp);
                }
     );
}
jQuery.getJSON() loads Json-encoded data from the server using a HTTP GET request.
jQuery.getScript() loads javaScript from the server using a HTTP GET request and execute it.

The shorthand methods are all in the form jQuery.methodname (or $.methodname). There is also a shorthand that you can apply on an element to load new data:

.load() Load data from the server and place the returned HTML into the matched element. This could be used in combination with a controller method that returns a partial view.
$('#data').load('@Url.Action("SomeData", "Test", new {id = Model.id})');

JSONP and CORS

For security reasons many browsers block requests to other domains. For this reason jQuery offers support for the JSONP (‘JSon with Padding’ or ‘Json with Prefix’) protocol.

Another option is to use CORS (Cross-origin resource sharing), but this is not supported by older browsers. It also requires some work on the server side: either by adding a header programatically:

Response.AppendHeader("Access-Control-Allow-Origin", "*");

or, by adding some configuration to the web.config:

<system.webServer>

    <httpProtocol>;
      <customHeaders>
        <clear>
          <add name='Access-Control-Allow-Origin' value='*' />;
      </customHeaders>
    </httpProtocol>

..

When using JSONP or CORS to post to another domain you should be very careful as this introduces a security risk to the application.

Advertisements