Introduction
In this article, I will demonstrate three different ways to call a server side method written in C# (ASP.NET) from client side using jQuery AJAX.
Background
Everyone knows that we use AJAX in websites in order to improve performance. jQuery is the latest and most widely used JavaScript library at present.
I have seen several sites using jQuery and was highly impressed with the functionalities it provides, so I thought to start with jQuery myself.
I have categorized invoking server methods from the client side in three categories:
- Call server methods without parameters and get response.
- Callserver methods with a simple parameter (integer or string value) and get response.
- Call server methods with a complex (JSON object) parameter and get response.
There is a very slight difference in these categories, but I found that people generally get stuck here and invest a lot of time in identifying the difference.
Though I have attached a running sample with this article, I would suggest creating the sample as per the steps mentioned below to get everything clear.
Steps to Create the Sample Application
Create an ASP.NET Website:
Create a folder named Scripts in the application and add a reference to “System.Web.Extensions.dll” (this DLL is present in the sample code attached).
Now add the following jQuery files in the Scripts folder:
- jquery-1.6.2.js or jquery-1.6.2.min.js
- jquery.json-2.2.js or jquery.json-2.2.min.js
It is preferred to use the min version. You can get these files from the sample or download them from www.jquery.com.
Now add a new JavaScript file in the Scripts folder in which we will write our script, and give it any name; I have named it “MyJQuery.js”.
Till now, we have only done the initial setup. Now let us start coding.
MethodInvokeWithJQuery.aspx
Add a reference to the .js files in the head
section and add the styles to be used.
<script type="text/javascript"
language="javascript"
src="Scripts/jquery-1.6.2.min.js"></script>
<script type="text/javascript"
language="javascript"
src="Scripts/jquery.json-2.2.min.js"></script>
<script type="text/javascript"
language="javascript"
src="Scripts/MyJQuery.js"></script>
<style type="text/css">
body
{
font-family:Arial;
font-size:.93em;
}
#tblAjaxDemo p
{
border:1px solid #EEE;
background-color:#F0F0F0;
padding:3px;
}
#tblAjaxDemo p span
{
color:#00F;
display:block;
font:bold 21px Arial;
float:left;
margin-right:10px;
}
</style>
Now add the controls. I have added three buttons and three div elements on this page, as follows:
<div>
<h1>
Demo page: Server Side Method Call Demo using JQuery and ASP.Net
</h1>
<p>
This page is a demo for calling server side methods using ajax capabilities of jquery.
</p>
<p style="margin: 20px 0; background-color: #EFEFEF;
border:1px solid #EEE; padding: 3px;">
Author: Praveen Meghwal
</p>
<table id="tblAjaxDemo" width="100%"
cellpadding="1" cellspacing="0" border="0">
<tr style="height: 10px;">
<td colspan="2" align="right">
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>1</span>This is button will call server side
method from JQuery and get response from server.
</p>
</td>
</tr>
<tr valign="top">
<td style="width: 30%;">
<asp:Button ID="btnTest" runat="server" Text="Click Me" />
</td>
<td style="width: 70%;">
<div id="myDiv" style="font-family:Arial; color: Red;">
</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr style="size: 2; color: Navy;" />
</td>
</tr>
<tr style="height: 20px;">
<td colspan="2">
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>2</span>This is button will call server side method from JQuery
along with parameter and get response from server. In this approach
only numeric value parameters are accepted.
Here I am passing numeric value 2 as parameter.
</p>
</td>
</tr>
<tr valign="top">
<td>
<asp:Button ID="btnTest2" runat="server" Text="Click Me" />
</td>
<td>
<div id="myDiv2" style="font-family:Arial; color: Red;">
</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr style="size: 2; color: Navy;" />
</td>
</tr>
<tr style="height: 20px;">
<td colspan="2">
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>3</span>This is button will call server side method from JQuery sendig complex
datatype (JSON object) to server and get response from server.
</p>
</td>
</tr>
<tr valign="top">
<td>
<asp:Button ID="btnTest3" runat="server" Text="Click Me" />
</td>
<td>
<div id="myDiv3" style="font-family:Arial; color: Red;">
</div>
</td>
</tr>
</table>
</div >
We are done with the ASPX stuff, now let us move to the .cs file (i.e., C# code).
MethodInvokeWithJQuery.aspx.cs
In MethodInvokeWithJQuery.aspx.cs, I added three web methods which we will invoke from the client side using jQuery. I have also added a class
Employee
which can be considered as the server side replica of the JavaScript object we are using in this demo. There is one more method which will convert
the client side complex object to the server side equivalent.
Employee
class: This class is created to simulate the JavaScript object passed from the client side.
public class Employee{
private string _firstName;
private string _lastName;
private string _technology;
private int _age;
public string FirstName
{
get
{ return _firstName; }
set
{ _firstName = value; }
}
public string LastName
{
get
{ return _lastName; }
set
{ _lastName = value; }
}
public string Technology
{
get
{ return _technology; }
set
{ _technology = value; }
}
public int Age
{
get
{ return _age; }
set
{ _age = value; }
}
}
WebMethods: These methods will be invoked from the client side using jQuery. In order to add WebMethod
attributes to the methods, add
"using System.Web.Script.Services;
" in the namespaces section.
[WebMethod]
public static string MethodWithNoParameter()
{
return "Message from server.";
}
[WebMethod]
public static string MethodWithNumericParameter(string strParam)
{
return "Parameter sent to server from client side is "
+ strParam;
}
[WebMethod]
public static string MethodWithComplexParameter(object jsonParam)
{
Employee objEmployee = GetEmployee(jsonParam);
return "Parameter sent to server from client side as " +
"follows:<br/>First Name => " +
objEmployee.FirstName + "<br/>Last Name => " +
objEmployee.LastName + "<br/>Technology=> " +
objEmployee.Technology + "<br/>Age => " + objEmployee.Age;
}
GetEmployee
method: This method will parse the JavaScript object to
the server side equivalent.
public static Employee GetEmployee(object employee)
{
Employee objEmployee = new Employee();
Dictionary<string, object> tmp = (Dictionary<string, object>)order;
object objFirstName = null;
object objLastName = null;
object objTechnology = null;
object objAge = null;
tmp.TryGetValue("FirstName", out objFirstName);
tmp.TryGetValue("LastName", out objLastName);
tmp.TryGetValue("Technology", out objTechnology);
tmp.TryGetValue("Age", out objAge);
objEmployee.FirstName = objFirstName.ToString();
objEmployee.LastName =
objLastName.ToString();
objEmployee.Technology =
objTechnology.ToString();
objEmployee.Age = objAge.ToString();
return objEmployee;
}
In this file, we will add the JavaScript code required to run the application like: binding the event to the buttons placed on the ASPX page
and setting the AJAX attributes required to invoke the server side methods.
Following is the JavaScript code:
var Employee = function(fName, lName, technology, age)
{
this.FirstName = fName;
this.LastName = lName;
this.Technology = technology;
this.Age = age;
}
$(document).ready (
function ()
{
try
{
$('#btnTest').click
(
function ()
{
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNoParameter",
data: "{}",
contentType: "application/json;
charset=utf-8",
dataType:"json",
async: true,
cache: false,
success: function (msg)
{
$('#myDiv').text(msg.d);
},
error: function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
$('#btnTest2').click
(
function ()
{
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNumericParameter",
data: "{'strParam' : 2}",
contentType: "application/json;
charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function
(msg)
{
$('#myDiv2').text(msg.d);
},
error:
function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
$('#btnTest3').click
(
function ()
{
var jsEmp = new Employee("Praveen", "Meghwal", "Microsoft Dotnet", 31);
var jsonText = $.toJSON(jsEmp);
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithComplexParameter",
data: "{'jsonParam' : " + jsonText + "}",
contentType: "application/json;
charset=utf-8",
dataType: "json",
async:
true,
cache: false,
success: function (msg)
{
$('#myDiv3').html(msg.d);
},
error: function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
}
catch(err)
{
alert(err);
}
}
);
Now let us see the code line by line.
In the top, we have defined the JavaScript object Employee
, which has four properties same as the server side.
var Employee =function(fName, lName, technology, age)
{
this.FirstName = fName;
this.LastName = lName;
this.Technology = technology;
this.Age = age;
}
Then we have used the document.ready()
function to perform operations on the controls once the DOM for the page is available for operation.
$(document).ready();
In the document.ready()
function, I have bound click events for all the three buttons. While binding, I have used the ajax()
method of jQuery. In this
method, I have specified the different parameter values including which server side method to invoke.
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNoParameter",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function
(msg)
{
$('#myDiv').text(msg.d);
},
error: function (x, e)
{
alert("The call to the server side failed. "+ x.responseText);
}
}
);
Above is the ajax
method declaration for the first button. Here, in the url
property, we specify the server side method name to invoke followed by
the page name. In the data
property, we set the parameter values to be passed to the method. In the case of the first button, we are not passing any parameter so we just
added "{}" here. But in the case of the second and third buttons, you will see I have used [data: "{'strParam' : 2}"]
and [data: "{'jsonParam' : " + jsonText + "}"]
, respectively.
Now let us see what is the difference between the second and third approach.
The second approach will work fine if you pass an inbuilt data type value as a parameter to it. For example: [data: "{'strParam' : 2}"]
and
[data: "{'strParam' : ‘string value’}"]
.
Now what if we want to pass user defined JavaScript objects as parameters? For this scenario, we will have to use the third approach, i.e.,
[data: "{'jsonParam' : " +
jsonText + "}"]
. Here, the variable
jsonText
is a string representation of the JavaScript object we have created. See the binding code for the third button,
where I have written the following lines:
var jsEmp = new Employee("Praveen", "Meghwal", "Microsoft Dotnet", 31);
var jsonText = $.toJSON(jsEmp);
Here we have used the $.toJSON ()
method of jQuery in order to convert it to the equivalent string representation. In order to
use this method, I have added a reference to the jQuery file "jquery.json-2.2.min.js." We can also use the JSON.stringify()
method,
but here JSON is only available if there is inbuilt JSON support in the browser.
In the success
property, we specify the client script to call after successful completion of an asynchronous call to the server.
In the error
property, we specify the client script to call in case any error occurs.
We are done with the coding part. Now run the application, and check whether the code is running properly or not. If you get an alert displaying
the error, got to the web.config file and check the System.Web
tag under configuration. It should look like:
="1.0"
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<authentication mode="Windows"/>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
</system.web>
</configuration>
If your web.config is not as displayed, add inner tags in the httpHandlers
and httpModule
tags as specified in the web.config.
Output:
Points of Interest
I have wasted a lot of time implementing server methods call with complex parameters. I searched on the net for help and every where, I found solutions to pass JSON text returned
from $.toJSON(jsEmp)
as a parameter to the server side. I tried this but did not work for me. Then I thought using the technique used in the second approach for sending
an inbuilt type parameter to the server side. I thought that the function $.toJSON(jsEmp)
converts JSON to string representation so the second approach should work,
and then I tried [data: "{'jsonParam' : " + jsonText + "}" ]
and succeeded.
History
First version.