Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MVC and Asynchronous Calls

0.00/5 (No votes)
23 Feb 2014 1  
MVC and asynchronous calls

Introduction

This tip will show you how to make asynchronous calls from ASP.NET MVC views using Ajax helper and JQuery and the required settings.

Often, we want to issue requests to controller actions from a view to update some sections without having to load the whole page and by the same time experiencing the famous page flickering, focus losing on some controls,...I think you get the idea!

The solution is obvious: make an asynchronous request. MVC Ajax helper and JQuery make that just simple and easy to do. And the way I think about it is in the Partial Rendering of the old ASP.NET Update Panel.

At the beginning, you have to make sure that your MVC project has a bundle script for your favorite JQuery version. You can check that in the BundleConfig class under App_Start folder.

You should have something as follows:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js"));

And then in the _Layout view (which is the master page for ASP.NET WebForms folks!) under Shared folder:

 @Scripts.Render("~/bundles/jquery")

These are part of bundling and minification of ASP.NET MVC. It means that MVC framework will emit for you the references to your scripts and styles with one line of code and will minify them in release mode. This can boost a little bit the performance of your application because the minification versions of scripts and styles are lighter.

Of course, you could reference the minification versions of JavaScript libraries but then you cannot combine styles or scripts in a single minified file.

One other thing that can help performance of your application, is to reference the scripts and styles in the bottom of _Layout view whenever possible and leave the section script empty in the other views:

@section scripts {

}

This way, your browser will not wait to download all the scripts and styles files. You could also use a cdn fallback here but it's another topic!

Back, to our Ajax request. Let’s say that we want to update the following division with some sort of data coming from server side controller.

<div id=”mydiv”>
selected date: <input type="text" id="datepicker"></p>
updated date from server: <input type="text" id="dateUpdated"></p>
</div>

Note that you may make it as partial view also if you have some sort of pattern that should be repeated and it happens often in those scenarios. You should avoid having your views rendered many times. I mean, if some HTML controls seem to appear more than one time on your view (when rendering partial views). If you find yourself with this problem at hand, just go to controller and try to control what should be rendered:

if(Request.IsAjaxRequest(){
// return only the piece of information needed or the partial view etc.
}

And then, add the JQuery script to make a Datepicker:

$(function() {
   $( "#datepicker" ).datepicker();
 });

And then, add the following code:

@using(ajax.BeginForm(
		new AjaxOptions{
				HttpMethod=”get”,
				InsertionMode=InsertionMode.Replace,
				UpdateTargetId=”mydiv”

}))

{
<input type =”submit” value =”search”/>
}

Basically, we are doing here a Get request and want to replace the content of the specified area (“mydiv” in this case). You may add some fading in and out using JQuery to make it obvious that your section is updated. I leave it to you as an exercise.

Now, if you take a look at the source of your view, you will notice some data-ajax-method and data-ajax-mode. Those attributes are part of HTML5 specifications. It is data for applications to consume and the browser ignores them. This means that even if your JavaScript is not enabled in your browser, those Ajax calls will still work. The client validation works the same way. This is the Unobtrusive JavaScript.

Now let’s use JQuery to achieve the same thing. First, we need to get rid of the Ajax.BeginForm and replace it by a regular one as follows:

<form method= "get" action= "@Url.Action(index)" data-m2a-ajax= "true" data-m2a-target = "#mydiv">

Note that @Url.Action(index) is reference to our controller action.

Add a new script file to your project and don’t forget to add it to the bundle just after JQuery.

Inside the file, code the following:

$(function()
{
var ajaxFormSubmit = function(){
var $form = $(this); //gives access to the form
var options = {
url: $form.attr("action"),
type: $from.attr("method"),
data: $form.serialize()
};

$.ajax(options).done(function (data){

var $theDiv= $($form.attr("data-m2a-target"));
$theDiv,replaceWith(data);

});

return false;// to prevent the browser from going away!

$("form[data-m2a-ajax= 'true']").submit(ajaxFormSubmit);

});

Here, when the submit button is hit, we call ajax FormSubmit function to handle the form submission. So we grab the reference to the form like this:

var $form = $(this);

It’s considered a good practice to begin any JQuery object by $ to be able to recognise easily. But it’s up to you.

Then handle the submission of the form by adding some options just as we did previously in the Ajax helper call. Use: $.ajax(options) to do the call by wiring also the callback function when it’s done. The data contains all the data that comes back from the server. So find the element for which you want to replace the content and go ahead replace it by data:

var $theDiv= $($form.attr("data-m2a-target"));
$theDiv.replaceWith(data);

Of course, we could make this JQuery code a little better and managing errors or handling exceptions. But I leave it to the reader.

Hope this will help somebody somewhere...

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here