Ajax Based Polling in ASP.NET Web Forms and MVC
Recently a reader asked as to how Ajax polling can be implemented in ASP.NET
applications. This short post attempts to answer that question.
While developing real-time applications you have multiple choices:
- Use Ajax based polling
- Use HTML5 Server Sent Events (SSE)
- Use libraries such as SignalR
While I have already illustrated
SSE and
SignalR approaches this post focuses mainly on Ajax based polling in ASP.NET
web forms and ASP.NET MVC.
In real-time applications the UI needs to be informed whenever some
interesting event happens on the server. Consider, for example, that you are
developing a graphical stock ticker that continuously displays stock prices in a
web page. The data needed by the application is generated on the server. The
moment new data is generated you need to update the web page so as to reflect
the changed data.
In the SSE and SignalR techniques mentioned above the server sends a
notification to the client whenever some interesting event happens on the
server. On the other hand Ajax base polling involves the client side code
periodically checking the server for some status change. To demonstrate how Ajax
based polling can be used in ASP.NET we use jQuery $.ajax() in combination with
a web method (web forms) and an action method (MVC).
Let's assume that the processing on the server is going to produce a text
file (say flag.txt). Whenever this file comes into existence on the server the
client needs to be updated accordingly. We are using a text file here purely as
a matter of convenience during testing and to skip any database logic for the
sake of simplicity.
The following code shows a web method that resides in the code behind of a
web form:
[WebMethod]
public static bool GetStatus()
{
if(File.Exists(HttpContext.Current.Server.MapPath("~/flag.txt")))
{
return true;
}
else
{
return false;
}
}
Notice that the GetStatus() method is a static method and is marked with [WebMethod]
attribute. The GetStatus()method simply checks for the existence of flag.txt
file in the root folder of the website using File.Exists() method. If file
exists on the server GetStatus() returns true, otherwise it returns false.
To call this web method periodically using jQuery $.ajax() add the following
code to the web form:
$(document).ready(function () {
setTimeout(CheckStatus, 3000);
});
function CheckStatus() {
var options = {};
options.url = "WebForm1.aspx/GetStatus";
options.type = "POST";
options.dataType = "json";
options.contentType = "application/json";
options.success = function (data) {
$("#msg").html("<h2>Status : " + data.d + "</h2> ");
if (!data.d) {
CheckStatus();
}
};
$.ajax(options);
}
Notice the code carefully. The ready() handler calls JavaScript setTimeout() to
trigger CheckStatus function after a delay of 3000 milliseconds. The CheckStatus()
function uses $.ajax() to make a POST request to the GetStatus() web method. The
options object specifies various settings needed while making the Ajax call. The
url property points to the web method. Notice how the URL is mentioned -
WebForm1.aspx/GetStatus. The dataType and contentType properties indicate the
request and response data types respectively. The success function is invoked
when the web method is called successfully. The success function receives a
parameter - data - that wraps the return value from the web method. The data.d
will give the return value - true or false - and is shown in a <div> element using html() method of jQuery. If data.d is false it indicates that
the file doesn't exist on the server and hence polling needs to be
continued. CheckStatus() is then recursively called to keep calling the
GetStatus() web method.
Ok. This was web form version of the code. If you want to do the same thing
in ASP.NET MVC you need to call an action method from the client side. Have a
look at the following action method:
public JsonResult GetStatus()
{
if (System.IO.File.Exists(Server.MapPath("~/flag.txt")))
{
return Json(true);
}
else
{
return Json(false);
}
}
This time GetStatus() is an action method. It returns true or false depending
on the existence of flag.txt file. Notice that the return type of GetStatus() is
JsonResult. The Json() method is used to convert .NET Boolean value to its JSON
equivalent and then it is sent to the client.
The client side code remains almost identical with a few changes. The jQuery
code goes in the Index view and CheckStatus() method needs a few changes as
shown below:
function CheckStatus() {
var options = {};
options.url = "Home/GetStatus";
options.type = "POST";
options.dataType = "json";
options.contentType = "application/json";
options.success = function (data) {
$("#msg").html("<h2>Status : " + data.d + "</h2> ");
if (!data.d) {
CheckStatus();
}
};
$.ajax(options)}
Notice the url property. Now it points to Home/GetStatus. Also notice that
the return value is directly accessible as the parameter (data) of the success
function and there is no need to use data.d.
That's it! Run the code and see if the polling happens as expected.