Click here to Skip to main content
15,867,453 members
Articles / Web Development / ASP.NET

AJAX for Beginners (Part 3) - Calling Server Side Methods and Consuming Web Services from JavaScript in an ASP.NET Website

Rate me:
Please Sign up or sign in to vote.
4.96/5 (34 votes)
14 Jan 2013CPOL9 min read 127.1K   2.7K   77   17
How to use ASP.NET AJAX Framework to call the methods defined on server side and how to invoke and use a web service from JavaScript
This article is Part 3 in a 3 part series on AJAX for beginners. In this part, you will learn how to call server side methods and consume Web Services from JavaScript in an ASP.NET website.

There are three articles in this mini series:

Introduction

In this article, we will try to see how we can use ASP.NET AJAX framework to call the methods defined on server side, i.e., code behind from client side JavaScript. We will also look at how we can invoke and use a Web Service from JavaScript.

Background

There are many times in our application when we want to have some functionality on client side which is already existing on the server side. If we have some independent piece of code running on server side, then there is no need to rewrite it in JavaScript on client side. We can simply use ASP.NET Ajax framework to call the methods from server side.

Another benefit of using server side code is that we get all the benefits of server side language and APIs and return the result on the client side. This is sometimes very useful, given the fact that C# is way more powerful than JavaScript and .NET Framework provides a wider range of functionalities.

We can also use ASP.NET AJAX framework to invoke and use Web Services from JavaScript. Having the possibility of invoking and using web services from JavaScript gives us the possibility of creating highly responsive user interface using the web services.

Note: There are few limitations when using ASP.NET AJAX framework. The server side methods that are being called from client side have to be static and none of the controls on the page can be referenced in the server side code that is being called by the client side. So having this functionality is really useful when I have an independent piece of algorithm that can be called on some input data and some output could be produced.

Using the Code

All these functionalities and communication between client side and server side is taken care by ASP.NET AJAX framework. To use the ASP.NET AJAX framework, we simply need to put a ScriptManager control on the page and it will take care of the rest.

To perform all the above mentioned tasks, we need to write the actual server side code that contains the functionality and the JavaScript code to call these server side code. All the boilerplate code that takes care of the communication between client and server is the ASP.NET AJAX frameworks responsibility. Let us try to understand how these can be done by looking at a sample application.

Calling a Simple Server Side Method

So the very basic possibility is to have a method on the server side and call it from JavaScript. Let us first define a function in our code behind file that will simply return some string message.

C#
[WebMethod]
public static string GetMessage()
{   
    return "Dummy Message";
}

To make this method callable from the client side script, we need to make this static and decorate/adorn it with a WebMethod attribute.

The first thing that we need to do to be able to call the server side methods is to make the EnablePageMethods="true" in the ScriptManager control.

ASP.NET
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"/>

Now let's have a button on the aspx page that will call this method using JavaScript.

ASP.NET
<asp:Button ID="Button1" runat="server" Text="Get Message"
 OnClientClick="CallServerMethod(); return false;" />

The CallServerMethod method is the JavaScript method that takes care of calling the server side method. The false is returned so that the default action of causing a postback is suppressed. Let us now look at the JavaScript function which is actually calling the server side method.

JavaScript
function CallServerMethod()
{
    // call the server side method here
    PageMethods.GetMessage(OnSuccess);       
}

The way to call the server side methods is to call the method defined in page using PageMethods. The argument that we need to pass to call the parameterless function is the name of the callback function that will be called to get the result. Let's look at this callback function.

JavaScript
function OnSuccess(result)
{
    alert(result);
}

Now when we run this page, the CallServerMethod will be called. In this method, we will call the server side method using PageMethods and passing the name of the callback function OnSuccess. The return value of the server side method will come as parameter in our callback function, i.e., result. Let us run the page to see the result.

Image 1

Passing Values and Getting Results from Server Side Methods

Now that we are able to call a simple method from client side, let us look at how we can pass the values from client side to the server side functions. To do this, let us try to write a simple calculator functionality. Let us take two inputs from the user and pass them to the server side and get back the result from server and show it to the user. In case the input is not valid, the server side should send us an error and we will show the error to the user.

Now to do this, first we need two input fields and a buttons to initiate the respective actions of Addition, Subtraction, Multiplication and Division.

ASP.NET
A: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
B: <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button2" runat="server" 
 Text="A+B" OnClientClick="CallServerAdd(); return false;" />
<asp:Button ID="Button3" runat="server" 
 Text="A-B" OnClientClick="CallServerSub(); return false;"  />
<asp:Button ID="Button4" runat="server" 
 Text="A*B" OnClientClick="CallServerMul(); return false;"  />
<asp:Button ID="Button5" runat="server" 
 Text="A/B" OnClientClick="CallServerDiv(); return false;"  />

Now each of these buttons calls a server side method to initiate the respective server side function. Let us look at the implementation of Add function and other functions will be implemented on same lines.

JavaScript
function CallServerAdd()
{
    var a = document.getElementById('TextBox1').value;
    var b = document.getElementById('TextBox2').value;
    PageMethods.Add(a, b, OnResult,OnError);
}

What we are doing in this function is that we are extracting the values form the text boxes and passing it to a server side method called Add. The third parameter OnResult is the callback function which will be called when method call is successful and the fourth OnError will be called when there is some error.

JavaScript
function OnResult(result,userContext, method)
{
    var resultMsg = "Result from Method [" + method +"] is: " + result;
    alert(resultMsg);         
}

function OnError(error, userContext, method)
{
    if(error != null)
    {
        var resultMsg = "Error from Method [" + method +"] is: '" + error.get_message() + "'";
        alert(resultMsg);
    }
}

These callback functions actually have the possibility to tell us the method from which they are being invoked, i.e., the method parameter in the functions. So we can actually use the same callback function for all four functions and get the results. We will show the result with the method name to know what method is giving the result or error.

So let's implement the other three functions too.

JavaScript
function CallServerSub()
{
    var a = document.getElementById('TextBox1').value;
    var b = document.getElementById('TextBox2').value;
    PageMethods.Sub(a, b, OnResult, OnError);
}

function CallServerMul()
{
    var a = document.getElementById('TextBox1').value;
    var b = document.getElementById('TextBox2').value;
    PageMethods.Mul(a, b, OnResult, OnError);
}

function CallServerDiv()
{
    var a = document.getElementById('TextBox1').value;
    var b = document.getElementById('TextBox2').value;
    PageMethods.Div(a, b, OnResult, OnError);
}

Now we need to write the server side functions that accept two input parameters, calculate the result and return the result. These functions could also throw the exceptions that will be handled by our client side error callback functions.

C#
[WebMethod]
public static string Add(string a, string b)
{
    string result = "ERROR";
    try
    {
        int ai = Convert.ToInt32(a);
        int bi = Convert.ToInt32(b);

        int res = ai+bi;
        result = res.ToString();
    }
    catch
    {
        throw;
    }
    return result;
}

[WebMethod]
public static string Sub(string a, string b)
{
    string result = "ERROR";
    try
    {
        int ai = Convert.ToInt32(a);
        int bi = Convert.ToInt32(b);

        int res = ai - bi;
        result = res.ToString();
    }
    catch
    {
        throw;
    }
    return result;
}

[WebMethod]
public static string Mul(string a, string b)
{
    string result = "ERROR";
    try
    {
        int ai = Convert.ToInt32(a);
        int bi = Convert.ToInt32(b);

        int res = ai * bi;
        result = res.ToString();
    }
    catch
    {
        throw;
    }
    return result;
}

[WebMethod]
public static string Div(string a, string b)
{
    string result = "ERROR";
    try
    {
        int ai = Convert.ToInt32(a);
        int bi = Convert.ToInt32(b);

        int res = ai / bi;
        result = res.ToString();
    }
    catch
    {
        throw;
    }
    return result;
}

Note: The implementation is just to demonstrate the client-server communication. The server side code is not optimized or refactored in any way.

Now when we run the application, we can see the result as:

Image 2

Passing and Returning Objects to Client Side from Server Side

Now we have seen how we can pass the data to and from client side to server side. This section specially discusses the possibility of using JSON so that if I have to return more than one value to client side, then I can encapsulate all these values in a class, serialize it in JSON format and return it to client side.

Let us have a simple class that encapsulates two integer fields:

C#
[DataContract]
public class PairOfInts
{
    int value1;

    [DataMember]
    public int Value1
    {
        get { return value1; }
        set { value1 = value; }
    }
    
    int value2;

    [DataMember]
    public int Value2
    {
        get { return value2; }
        set { value2 = value; }
    }

    public PairOfInts(int p1, int p2)
    {
        Value1 = p1;
        Value2 = p2;
    }

    public static PairOfInts operator ++(PairOfInts p)
    {
        p.Value1 += 1;
        p.Value2 += 1;

        return p;
    }
}

We have to decorate/adorn this class with DataContract attribute so that it can be serialized in JSON format. The members that need to be included in JSON format have to be public and decorated with DataMember attribute.

Now let us write a simple server side function that creates an object of this type and returns the JSON representation string of this object.

C#
[WebMethod]
public static string GetSamplePairOfInts()
{
    // Create a dummy pairofints object
    PairOfInts pair = new PairOfInts(13, 17);

    // Let us create a JSON serializer for it
    DataContractJsonSerializer jsonMaker = new DataContractJsonSerializer(typeof(PairOfInts));

    // USe a memory stream to hold the json converted data
    using (MemoryStream ms = new MemoryStream())
    {
        // convert our class to json
        jsonMaker.WriteObject(ms, pair);
        ms.Flush();

        // get the bytes of json representation of our class
        byte[] bytes = ms.GetBuffer();

        // return the json string to the client side caller
        string jsonResult = Encoding.UTF8.GetString(bytes, 0, bytes.Length).Trim('\0');
        return jsonResult;
    }
}

Now from the client side, all we need to do is to call this method. The callback that handles the success will have to evaluate this JSON string to a JavaScript object using eval method and then display the result to the user. So let us see the JavaScript code that calls this method, handles the success and handles the error.

JavaScript
function CallSamplePair()
{
    PageMethods.GetSamplePairOfInts(OnJSONGetSuccess, OnJSONGetFailure);       
}
    
function OnJSONGetSuccess(result, userContext, method)
{
    if(result != null)
    {
        var PairOfInts = eval('('+ result + ')');
    
        var resultMsg = "Pair from Method [" + method +"] is: 
                        (" + PairOfInts.Value1 + ", " + PairOfInts.Value2 + ")";
        alert(resultMsg);         
    }
}

function OnJSONGetFailure(error, userContext, method)
{
    if(error != null)
    {
        var resultMsg = "Error from Method [" + method +"] is: '" + error.get_message() + "'";
        alert(resultMsg);
    }
}

Now when we call this method, the object will be created on server side and will be returned to the client side as JSON.

Image 3

This functionality can also be extended to get some values from the client side, create an object based on these values on server, perform some operation on the object and then return the updated object in JSON format.

To see this, let us implement the logic of incrementing a pair Object using the overloaded operator on server side. This will be called from client and result will be shown using a JSON.

The server side method is as follows:

C#
[WebMethod]
public static string IncrementPairOfInts(string val1, string val2)
{
    // get the values from the user
    int a = Convert.ToInt32(val1);
    int b = Convert.ToInt32(val2);
 
    // create a pair class
    PairOfInts pair = new PairOfInts(a, b);

    // increment the pair object
    pair++;

    // Let's create a JSON serializer for it
    DataContractJsonSerializer jsonMaker = 
                new DataContractJsonSerializer(typeof(PairOfInts));
    
    // Use a memory stream to hold the json converted data
    using (MemoryStream ms = new MemoryStream())
    {
        // convert our class to json
        jsonMaker.WriteObject(ms, pair);
        ms.Flush();

        // get the bytes of json representation of our class
        byte[] bytes = ms.GetBuffer();

        // return the json string to the client side caller
        string jsonResult = Encoding.UTF8.GetString(bytes, 0, bytes.Length).Trim('\0');
        return jsonResult;
    }
}

Client side JavaScript:

JavaScript
function IncrementPair()
{
    PageMethods.IncrementPairOfInts(document.getElementById('TextBox3').value, 
                                    document.getElementById('TextBox4').value, 
                                    OnJSONGetSuccess, OnJSONGetFailure);                
}

function OnJSONGetSuccess(result, userContext, method)
{
    if(result != null)
    {
        var PairOfInts = eval('('+ result + ')');
    
        var resultMsg = "Pair from Method [" + method +"] is: 
                        (" + PairOfInts.Value1 + ", " + PairOfInts.Value2 + ")";
        alert(resultMsg);         
    }
}

function OnJSONGetFailure(error, userContext, method)
{
    if(error != null)
    {
        var resultMsg = "Error from Method [" + method +"] is: '" + 
                         error.get_message() + "'";
        alert(resultMsg);
    }
}

When we run it, we can see the result on client side as:

Image 4

Calling a Web Service from JavaScript

Now we have seen how to call a simple server side method, how to call a server side method with some values, how to get return value from server side and how to get multiple return values in form of JSON.

One more important piece of functionality is to be able to call web services from JavaScript. To see how it can be done, let us create a simple sample web service that performs an addition.

C#
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class TestService : System.Web.Services.WebService {

    public TestService () {

    }

    [WebMethod]
    public int Add(int x, int y) {
        return x + y;
    }    
}

This service is decorated/adorned with the ScriptService attribute to make it possible to be called from JavaScript.

Now to be able to call this service from client side, we need to add a reference to this service in the ScriptManager. This can be done as:

ASP.NET
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
<Services>
    <asp:ServiceReference Path="TestService.asmx" />
</Services>
</asp:ScriptManager>

Once we have this service added in the list of ScriptManager services, we can simply call the methods of this service as:

JavaScript
function InvokeService()
{
    TestService.Add(document.getElementById('TextBox5').value,
                    document.getElementById('TextBox6').value,
                    OnServiceSuccess, OnserviceFailure, 'Webservice.Add');       
}

function OnServiceSuccess(result, userContext, method)
{
    var resultMsg = "Result from Method [" + userContext +"] is: " + result;
    alert(resultMsg);         
}

function OnserviceFailure(error, userContext, method)
{
    if(error != null)
    {
        var resultMsg = "Error from Method [" + userContext +"] is: '" + 
                         error.get_message() + "'";
        alert(resultMsg);
    }
}

The above code shows the function to invoke the service, i.e., InvokeService. The callback function that will be called on success, i.e., OnServiceSuccess. And the callback method that will be called on error, i.e., OnserviceFailure. Let us now run the application to see how this service can be invoked from JavaScript.

Image 5

One more thing to notice here is that we have used userContext here to pass some data from the caller of the service to the callback method. userContext is useful if we need to pass some data from calling methods to the callback. Because the callbacks can be called for various methods and even multiple times for the same method, userContext can be used to identify them.

Note: Downloading the sample code and running it will be very helpful because this article shows code snippets of C#, JavaScript and ASPX markup. So to get the complete picture, please refer to the sample code.

Point of Interest

So we have seen how we can call the server side methods from JavaScript using ASP.NET Ajax framework. We have also seen how we can consume web services from JavaScript. This article was written from a beginner's perspective. I hope this has been informative.

History

  • 10th January, 2013: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India

I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.

  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Accessing Data with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4

If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]

  • Microsoft MVP 2015

Comments and Discussions

 
QuestionHow to insert the stuff step-by-step in Visual Studio 2017 ? Pin
kayoumt24-Nov-18 16:49
kayoumt24-Nov-18 16:49 
QuestionMaking this project work. Pin
ChickenRigSoftware14-Jan-17 20:29
ChickenRigSoftware14-Jan-17 20:29 
Questionbrief description Pin
MUDANZAS VALENCIA mudanzasvalemcia.com18-Aug-15 21:49
MUDANZAS VALENCIA mudanzasvalemcia.com18-Aug-15 21:49 
QuestionAwesome Pin
Member 1064752921-Mar-14 5:49
Member 1064752921-Mar-14 5:49 
Questionexcellent article Pin
chait30113-Mar-14 0:42
chait30113-Mar-14 0:42 
QuestionError with result apply Pin
A.Ebrahimi9-Mar-13 0:17
A.Ebrahimi9-Mar-13 0:17 
GeneralMy vote of 5 Pin
Abinash Bishoyi4-Mar-13 5:18
Abinash Bishoyi4-Mar-13 5:18 
GeneralMy vote of 5 Pin
Pyledriver14-Feb-13 23:24
Pyledriver14-Feb-13 23:24 
GeneralMy vote of 5 Pin
SergheiT15-Jan-13 8:52
professionalSergheiT15-Jan-13 8:52 
GeneralMy vote of 5 Pin
resi243114-Jan-13 22:32
resi243114-Jan-13 22:32 
QuestionYour article says Part 3 Pin
Vaso Elias14-Jan-13 3:04
Vaso Elias14-Jan-13 3:04 
AnswerRe: Your article says Part 3 Pin
ohyeahbaby14-Jan-13 12:06
ohyeahbaby14-Jan-13 12:06 
GeneralRe: Your article says Part 3 Pin
Vaso Elias14-Jan-13 19:19
Vaso Elias14-Jan-13 19:19 
AnswerRe: Your article says Part 3 Pin
Rahul Rajat Singh14-Jan-13 17:27
professionalRahul Rajat Singh14-Jan-13 17:27 
GeneralRe: Your article says Part 3 Pin
ohyeahbaby16-Jan-13 21:01
ohyeahbaby16-Jan-13 21:01 
QuestionGreat Article Pin
vdykcj13-Jan-13 22:24
vdykcj13-Jan-13 22:24 
Where can I find Part 1 and 2?
Johan
(Who is General Failure and what is he doing on my machine)

AnswerRe: Great Article Pin
Rahul Rajat Singh14-Jan-13 0:04
professionalRahul Rajat Singh14-Jan-13 0:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.