How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX

You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client. However there are some workarounds. To call serverside code from javascript, you will need to use AJAX, and the easiest way out, is to use the ASP.NET AJAX Extensions.
One option while using Microsoft ASP.NET AJAX is to call ASP.NET Web services (.asmx files) from the browser by using client script. The script can call a webservice containing server-based methods (Web methods) and invoke these methods without a postback and without refreshing the whole page. However this approach could be overkill sometimes, to perform the simplest of tasks. Moreover the logic needs to be kept in a separate .asmx file. We need something that is more ‘integrated’ with our solution.
The option we are going to use in this article involves PageMethods. A PageMethod is basically a public static method that is exposed in the code-behind of an aspx page and is callable from the client script. PageMethods are annotated with the [WebMethod] attribute. The page methods are rendered as inline JavaScript.
Let us explore PageMethods with an example. The example we will be discussing here may not be the best example to explain PageMethods, but it will give you an idea of how to call server side code from client side. In this example, we will be connecting to the Customers table in the Northwind database. We will have some textboxes which will accept the CustomerID and in turn return the Contact Name of that Customer. The method returning ContactName will be called whenever the textbox loses focus. We will be using the onblur event where a javascript code will take in the value(CustomerID) from the textbox. This javascript function will then call a PageMethod (server side code) which returns the ContactName without any page refresh.
I assume that you have downloaded and installed ASP.NET AJAX extensions for ASP.NET 2.0. If not, I would advise you to download the extensions from here and install it before moving ahead. At any point of time, if you find a difficulty in understanding the code, download the sample project attached with this article at the end.
Step 1: Create an ASP.NET AJAX enabled website. Go to File > New > Website > ASP.NET AJAX-Enabled Web Site. Give the solution a name and location and click Ok.
Step 2: Drag and drop 2 labels and 4 textbox controls. We will be accepting the CustomerID from the user in the 2 textboxes and displaying the ‘ContactName’ in the other two textboxes. The textboxes that will display ‘ContactName’ has some properties set that will make it appear as a label without a border. Just set the BorderStyle=None, BorderColor=Transparent and ReadOnly=True. The markup will look similar to the following:
<form id=”form1″ runat=”server”>    
        <asp:ScriptManager ID=”ScriptManager1″ runat=”server”/>
        <div>
        <asp:Label ID=”lblCustId1″ runat=”server” Text=”Customer ID 1″></asp:Label>
        <asp:TextBox ID=”txtId1″ runat=”server”></asp:TextBox><br />
            <asp:TextBox ID=”txtContact1″ runat=”server” BorderColor=”Transparent” BorderStyle=”None”
                ReadOnly=”True”></asp:TextBox><br />
        <br />
        <asp:Label ID=”lblCustId2″ runat=”server” Text=”Customer ID 2″></asp:Label>
        &nbsp;
        <asp:TextBox ID=”txtId2″ runat=”server”></asp:TextBox><br />
            <asp:TextBox ID=”txtContact2″ runat=”server” BorderColor=”Transparent” BorderStyle=”None”
                ReadOnly=”True”></asp:TextBox>&nbsp;<br />
            </div>
    </form>
Before moving ahead, we will store our connection string information in the Web.config. Add the following tag below your </configSections> tag. Remember we have created an ‘ASP.NET AJAX enabled website’. The tag </configSections> along with some other tags automatically get added to the web.config.
<connectionStrings>
            <removename=all/>
            <addname=NorthwindConnectionStringconnectionString=Data Source=(local); Initial Catalog=Northwind; Integrated Security = SSPI;/>
      </connectionStrings>
Step 3: Currently we will add a method, ‘GetContactName()’ which will accept a CustomerID and return the Contact Name information from the Northwind database, Customer table. We will then transform this method as a PageMethod.
C#
public static string GetContactName(string custid)
    {
        if (custid == null || custid.Length == 0)
            return String.Empty;
        SqlConnection conn = null;
        try
        {
            string connection = ConfigurationManager.ConnectionStrings[“NorthwindConnectionString”].ConnectionString;
            conn = new SqlConnection(connection);
            string sql = “Select ContactName from Customers where CustomerId = @CustID”;
            SqlCommand cmd = new SqlCommand(sql, conn);
            cmd.Parameters.AddWithValue(“CustID”, custid);
            conn.Open();
            string contNm = Convert.ToString(cmd.ExecuteScalar());
            return contNm;
        }
        catch (SqlException ex)
        {
            return “error”;
        }
        finally
        {
            conn.Close();
        }
    }
VB.NET
 Public Shared Function GetContactName(ByVal custid As String) As String
        If custid Is Nothing OrElse custid.Length = 0 Then
            Return String.Empty
        End If
        Dim conn As SqlConnection = Nothing
        Try
            Dim connection As String = ConfigurationManager.ConnectionStrings(“NorthwindConnectionString”).ConnectionString
            conn = New SqlConnection(connection)
            Dim sql As String = “Select ContactName from Customers where CustomerId = @CustID”
            Dim cmd As SqlCommand = New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue(“CustID”, custid)
            conn.Open()
            Dim contNm As String = Convert.ToString(cmd.ExecuteScalar())
            Return contNm
        Catch ex As SqlException
            Return “error”
        Finally
            conn.Close()
        End Try
    End Function
Step 4: We will now transform this method as a PageMethod and then call this method GetContactName() from client side code; i.e. using JavaScript. To enable the method as a PageMethod, add the attribute [WebMethod] on top of the method:
C#
[System.Web.Services.WebMethod]
public static string GetContactName(string custid)
{
}
VB.NET
<System.Web.Services.WebMethod()> _
    Public Shared Function GetContactName(ByVal custid As String) As String
   End Function
At the sametime, add the attribute EnablePageMethods=”true” to the ScriptManager as shown below:
<asp:ScriptManager ID=”ScriptManager1″ runat=”server EnablePageMethods=”true”/>
Step 5: Let us now create the JavaScript that will call this server side code. Add a javascript file called script.js to your solution (Right Click Project > Add New Item > Jscript File > Rename file to script.js). Add the following code to the javascript file.
function CallMe(src,dest)
 {    
     var ctrl = document.getElementById(src);
     // call server side method
     PageMethods.GetContactName(ctrl.value, CallSuccess, CallFailed, dest);
 }
 // set the destination textbox value with the ContactName
 function CallSuccess(res, destCtrl)
 {    
     var dest = document.getElementById(destCtrl);
     dest.value = res;
 }
 // alert message on some failure
 function CallFailed(res, destCtrl)
 {
     alert(res.get_message());
 }
Step 6: We now need to reference this JavaScript file from our aspx page and invoke the ‘CallMe()’ method whenever the textbox loses focus. To do so:
Add a reference to the javascript file in the body tag as shown below:
<body>
<script type=”text/javascript” language=”javascript” src=”script.js”> </script>
    <form id=”form1″ runat=”server”>    
………
Step 7: To invoke the methods whenever the textbox looses focus, add these lines of code in the Page_Load() event
C#
if (!Page.IsPostBack)
        {
            txtId1.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId1.ClientID + “‘, ‘” + txtContact1.ClientID + “‘)”);
            txtId2.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId2.ClientID + “‘, ‘” + txtContact2.ClientID + “‘)”);
        }
VB.NET
If (Not Page.IsPostBack) Then
                  txtId1.Attributes.Add(“onblur”, “javascript:CallMe(‘” & txtId1.ClientID & “‘, ‘” & txtContact1.ClientID & “‘)”)
                  txtId2.Attributes.Add(“onblur”, “javascript:CallMe(‘” & txtId2.ClientID & “‘, ‘” & txtContact2.ClientID & “‘)”)
End If
As shown above, we are using the Attributes.Add that lets us add an attribute to the server control’s System.Web.UI.AttributeCollection object. The function ‘CallMe’ kept in the ‘script.js’ file will be invoked. We are passing the source and destination textboxes as parameters. The source textbox will contain the CustomerID. The CustomerID will be looked up in the Customers table and the corresponding ‘ContactName’ will be retrieved in the destination textbox.
Well that is all that is needed to invoke server side code from client side. Run the code. Type ‘ALFKI’ in the first textbox and hit the tab key. You will see that the javascript function goes ahead and calls the PageMethod GetContactName() using PageMethods.GetContactName. It passes the value of the source textbox which contains the CustomerID. The ‘ContactName’ returned is displayed in the second textbox below the first one, in our case the value displayed is ‘Maria Anders’.
Troubleshooting: ‘PageMethods Is ‘Undefined’’ error
1.    Try setting EnablePageMethods=”true” in the script manager tag
<asp:ScriptManager ID=”ScriptManager1″ runat=”server” EnablePageMethods=”true”/>
2.    Don’t add the javascript references or code in the <head /> section. Add it to the <body> tag.
<body>
<script type=”text/javascript” language=”javascript” src=”script.js”> </script>
    <form id=”form1″ runat=”server”> 
    </form>
</body>
3.    Page methods needs to be static in code behind.

39 thoughts on “How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX

  1. it’s very useful.
    thanx..

    but i’ve a diffculties in pagemethods’ parameters.
    how are these parameters used?

    • Hi,

      I am facing the same problem.

      I set EnablePageMethods=true for ScriptManager and added the script inside the body tag.

      Still I am getting error that MyPage is undefined.(where my aspx page class).

      Thanks and regards,
      Chetan Ranpariya

  2. Great work sappidireddy!!
    It’s very handy.
    I am using it in my ASP.NET application now and i was searching for such way out for days and found it here. But my scenario is a bit different. I am using tow Dropdownlists. One dropdown contains contains countries name & i want to bound the other dropdownlist (city dropdownlist) with city name for a country selected from the country dropdownlist. I am using onchange event of javascript for my country dropdownlist’s selected index change and as a result i am getting a datatable filled up on the base of country id.
    here is the Attribute.Add methods in code behind file:

    ddlCountries.Attributes.Add(“onchange”, “javascript:CallMe(‘” + ddlCountries.ClientID + “‘, ‘” + ddlLocations.ClientID + “‘)”);

    Here comes the problem. As i am getting a datatable from db,so i don’t know how to bind this datatable to city dropdownlist.
    Please guide me how to achieve this task.
    Thanks in advance

    • try like this.
      function addOption(ddl, text,value )
      {
      var optn = document.createElement(“OPTION”);
      optn.text = text;
      optn.value = value;
      ddl.options.add(optn);

      }

      function CallSuccess(res, destCtrl)
      {
      var dest = document.getElementById(destCtrl);

      for (i =0; i< res.count; i++)
      {
      addOption(ddl, res[i][0],res[i][1])
      }

      }

  3. Thanks for quick reply sappidireddy.
    I have used addOption function you have given and changed CallSuccess function as you supplied.
    But i am getting the following error (javascript error):
    ——————–
    A circular reference was detected while serializing an object of type ‘System.Reflection.Module’.
    ——————-
    I have put two Alerts in CallMe (javascript function) just before & after PageMethods. loadCountryWiseLocations(ctrl.value, CallSuccess, CallFailed, dest);

    like this:
    ——–
    alert(‘before calling server method’);
    PageMethods.loadCountryWiseLocations(ctrl.value, CallSuccess, CallFailed, dest);
    alert(‘after calling server method’);
    ———
    The error that i have written above is shown when second alert shows almost.
    I removed the For loop in CallSuccess function just to check whether this is causing error. And after removing the For loop the error is still there.

  4. Hi, Thank you for a great article,

    Unfortunately i’m getting the following error:

    PageMethod.CallMe is not a function.

    Have you experienced this error?

  5. i did not understand from where we are assigning “destCtrl” in this function CallSuccess(res, destCtrl).i have a situation where i need the destCtrl type variable to stop the page from postback

  6. Hello,

    This article is great undoubtedly. Thanks for sharing. One simple query. Te method you declared in the .VB or .CS page is a shared method and because of that, I am unable to access any server side control property. Can you please explain that. Also can we made call to another javascript function from this shared method?

    Please let us know.

    Thanks – Arin

  7. i am working on VS2008, and probably its different to declare de method. STEP 3 is less described than others steps ?

    could you help me to construct this module ?

    thanks a lot.

    farid

  8. hello
    i tried your example its working grt!!
    i have one question can we return datatable from webservice and bind it to grid view how can be this acheived..

  9. Hi sappidireddy,

    Hopefully you are doing well.Iam facing PageMethods undefined error in vs 2008.

    1) I set EnablePageMethods=true for ScriptManager and added the script inside the body tag.
    2) Put Static Mehtod in Code behind

    Iam looking forword for your response.

  10. Pingback: How to call an ASP.net WebService (OR WCF Service) using Jquery « Out of memory exception…..
  11. Your method must be public static

    [System.Web.Services.WebMethod]
    public static void ExportToCSVWebMethod()
    {

    And partial rendering is NOT needed.


    Orest Pipka

  12. Pingback: Autosurf
  13. Hello Venkat Reddy,

    It’s nice article. But I’m having problem on page using SSL (Secure Sockets Layer).
    Following js error arises :

    Error: Sys.ArgumentTypeException: Object of type ‘String’ cannot be converted to type ‘Object’.
    Parameter name: errorObject
    Source File: FileName Line: 7786

    Please give me solution….
    Thanks in advance.

  14. how can we do this using SSL?
    I’m getting js error follows:

    Error: Sys.ArgumentTypeException: Object of type ‘String’ cannot be converted to type ‘Object’.
    Parameter name: errorObject
    Source File: FileName
    Line: 7786

    Please reply, thanks in advance.

  15. in my visual web part, i.e in my “.ascx.cs”, I have a c# method for loading data. I want to call this method from JS so that I can load data asynchronously. how to call the method? because [System.Web.Services.WebMethod] doesn’t work in “.ascx.cs”.

  16. Ok, I finally got this page loading up, but the quote marks used in the code on this page are like “” and not “” which was giving me plenty of errors until fixed. Unfortunately, the Javascript is still not being called.

    txtId1.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId1.ClientID + “‘, ‘” + txtContact1.ClientID + “‘)”);
    txtId2.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId2.ClientID + “‘, ‘” + txtContact2.ClientID + “‘)”);

    I have this, if I remove the quotes from the javascript part then it just says “CallMe” does not exist in the current context”. I don’t know what I am doing wrong 😀

  17. I personally think this amazing post , Solar Screens For Windows “How
    to call Server Side function from Client Side
    Code using PageMethods in ASP.NET AJAX | Venkat Sappidi”,
    extremely engaging and the blog post was in fact a superb read.
    I appreciate it-Jess

Leave a reply to ash Cancel reply