Wednesday, May 30, 2012

Different ways for calling a code behind function from Javascript

Recently, one of my colleague asked about the different ways for calling a code behind function from JavaScript. There are different ways to call a code behind function and I decided to list down here each with example.

According to me, there are four main possible ways to call a function from Javascript:

1. Pagemethods in JS AND WebMethod in code behind class
2. IPostBackEventHandler in
codebehind class AND _doPostBack in JS 
3. ICallbackEventHandler in code behind class
4. Ajax/Jquery AND ASHX handler

Lets check each of above methods
with example and explanation.

1. Pagemethods in JavaScript AND WebMethod in cs

For using Pagemethods in JavaScript, we need to add Script Manager on aspx page. For using Ajax .Net (script manager, update panel) we need to add below settings in web.config and also System.Web.Extensions assembly is required.

<configuration>
    <system.web>
        <pages>
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
            </controls>
        </pages>   
    </system.web>
</configuration>
  

ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        PageMethods.GetCity("USA", onSucceeded, onFailed);
    }
    function onSucceeded(result, userContext, methodName) {
        document.getElementById("div1").innerHTML = result;
    }
    function onFailed(error, userContext, methodName) {
        alert("An error occurred")
    }
</script>

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
 


Codebehind Code:

[System.Web.Services.WebMethod()]
        public static string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }


Here 2 things need to take care:

1. Method in cs file must be public static and with attributes [System.Web.Services.WebMethod()]
2. Set EnablePageMethods="true" in Scriptmanager

2. IPostBackEventHandler in code behind class AND __doPostBack in JS

ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        var pageId = '<%=  Page.ClientID %>';
        __doPostBack(pageId, "USA");
    }
</script>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
<asp:Label id="lblInfo" runat="server"></asp:Label>

Codebehind Code:

public partial class SampelForm : System.Web.UI.Page, IPostBackEventHandler
    {

        public string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            string val = GetCity(eventArgument);
            lblInfo.Text += "City - " + val;
        }
    }


Here, with IPostBackEventHandler, Page is submitted to server (postback) and so user experience will NOT be as good compare to other methods.


3. ICallbackEventHandler in code behind class


ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        CallToServer('USA');
    }

    function ReceiveServerData(arg, context) {
        document.getElementById("div1").innerHTML = "Date from server: " + arg;
    }
</script>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
<asp:Label id="lblInfo" runat="server"></asp:Label>

Codebehind Code:

public partial class SampelForm : System.Web.UI.Page, IPostBackEventHandler
{

        public string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            string val = GetCity(eventArgument);
            lblInfo.Text += "City - " + val;
        }
}

Here, with ICallbackEventHandler, Page is NOT submitted to server and so user will experience a quick response from server (No Postback). 

4. Ajax/Jquery AND ASHX handler

ASPX Page Code:

//JQuery JS File is required.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>

<script language="javascript" type="text/javascript">

    function GetCityValue() {
        $.ajax({
            type: "POST",
            url: "AjaxHandler.ashx?method=getcity",
            dataType: "text",
            success: ReturnData2,
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert(textStatus);
            }
        });
    }

    function ReturnData2(data) {
        $("#div1").text(data);
    }

</script>
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>


Codebehind Code:

First of all we need to create a Handler class file. To add http handler class file (.ashx), right click on Project Name in Solution explorer and click on Add New Item. Click on Generic Handler and click Add button. It will add .ashx file, here in our example we name it as AjaxHandler.ashx.


Now copy the below code in ProcessRequest method:


        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString["method"] == null)
                return;
            string methodname = context.Request.QueryString["method"];
            MsgResponse objResponse = new MsgResponse();
            string Returnmsg = string.Empty;
            switch (methodname)
            {
                case "getcity":
                    context.Response.ContentType = "text/plain";
                    Returnmsg = Getcity();
                    break;
            }
            context.Response.Write(Returnmsg);
        }

        private string Getcity()
        {
            return "NewJersey";
        }



Here, we pass the method name in querystring from Javascript Ajax call (url: "AjaxHandler.ashx?method=getcity",) and check that method name in ASHX handler. Finally, what we write to context.Response.Write will be send back to Javascript. Here, we can also use JSON to send objects in JSON format. 


Here, each way has its own advantage and disadvantage. In my opinion method 1 with Pagemethods is useful if you want to call codebehind method rarely. If you are calling server side functions more frequently, its better to use 4th method (Ajax and ASHX handler) to call server side function.


Happy Programming !!!