Calling Web Service (asmx) From JavaScript Using PageMethods

TestService.ascx

namespace ScriptManagerService
{
    //The attribute which makes the web service callable from script.
    [System.Web.Script.Services.ScriptService]
    public class TestService : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

The above web service code is pretty straight forward. We have a simple “HelloWorld” method which returns a string. What makes this web service special is the “[System.Web.Script.Services.ScriptService]” attribute added on top of the “TestService” web service class. The attribute makes the web service callable from JavaScript. Also when the proxy classes are generated the attribute generates JavaScript object corresponding to the web service class. Once the web service is created now we need to create our web page to invoke the web method. Create a new aspx page and add a “ScriptManager” control to it. Sample aspx page with the “ScriptManager” tag is added below.

<body>
<script language="javascript" type="text/javascript">
function invokeSimpleWebMethod()
{
    ScriptManagerService.TestService.HelloWorld(handleResult);    
} 
 
function handleResult(result)
{
    alert(result);
}

</script>

   <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="scrMgr" runat="server">
            <Services>
                <asp:ServiceReference Path="TestService.asmx" />                
            </Services>
        </asp:ScriptManager>
        <asp:Button ID="btnHW" runat="server" Text="Hello World" OnClientClick="invokeSimpleWebMethod();" />
    </div>
    </form> 
</body>

In the above code we can see that we have a “ScriptManager” server control added. And inside the “Services” tag we have added reference to our local web service using the “ServiceReference” tag. The path attribute of the “ServiceReference” tag has the url of the web service which needs to be invoked. You can add multiple web services by adding additional “ServiceReference” tags. What ASP.NET does here is that it generates JavaScript proxy classes for each of the web services mentioned in the “ServiceReference” tag. All the auto generated JavaScript proxy classes derive from “Sys.Net.WebServiceProxy”.

Also we have an ASP.NET Button server control which calls a “invokeSimpleWebMethod” javascript method on its “OnClientClick” event. In the “invokeSimpleWebMethod” javascript method we have made use of the namespace (in which the web service is defined) followed by the web service name and finally the method name which needs to be invoked. Behind the scene ASP.NET has done the extra work of registering the namespace and creating the proxy classes and also adding the methods defined inside the web service into a proxy JavaScript class. If you notice the “HelloWorld” method takes an argument. The argument is nothing but the name of the JavaScript function which needs to be invoked when the web service method has been successfully executed and results are returned to the browser. You can also pass the name of the function which needs to be invoked when the web service method invocation request fails. We will see the same shortly. The “handleResult” JavaScript method gets called when the asynchronous request is successfully returned. The method gracefully displays the result in an alert message box.

That’ about how to use the “ScriptManager” server control to invoke a web service methods i.e. namespace followed by class name followed by the method name. One thing to note is that “ScriptManager” control can only be used to call web services in the same domain.

More info from source and here.

Real World Example:

PollWSAsync.asmx

<%@ WebService Language="C#" Class="PollWSAsync" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;


[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// The following attribute allows the service to 
// be called from script using ASP.NET AJAX.
[System.Web.Script.Services.ScriptService]
public class PollWSAsync : System.Web.Services.WebService
{

    [WebMethod]
    public bool PollCastVote(int PollAnswerID)
    {

        bool returnValue = false;

        Guid userID = Guid.NewGuid();
        DateTime dateTimeStamp = DateTime.Now;

        // connection string
        string connectionString = ConfigurationManager.ConnectionStrings["PollConnectionString"].ConnectionString;

        // Sql connection object initialized with connection string used to connect
        using (SqlConnection mySqlConnection = new SqlConnection(connectionString))
        {
            try
            {
                // open the Sql connection
                mySqlConnection.Open();

                // Sql Command object initialized with SQL INSERT
                SqlCommand mySqlCommand = new SqlCommand("INSERT INTO PollUserResponses (UserID, PollAnswerID, DateTimeStamp) VALUES (@UserID, @PollAnswerID, @DateTimeStamp)", mySqlConnection);
                mySqlCommand.Parameters.AddWithValue("@UserID", userID);
                mySqlCommand.Parameters.AddWithValue("@PollAnswerID", PollAnswerID);
                mySqlCommand.Parameters.AddWithValue("@DateTimeStamp", dateTimeStamp);

                // Execute
                mySqlCommand.ExecuteNonQuery();

                returnValue = true;

            }
            catch (Exception ex)
            {

            }
            finally
            {
                // close the Sql Connection
                mySqlConnection.Close();
            }

            return returnValue;

        }
    }
}

PollControlAsync.ascx

<script runat="server">
protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);      

    }
</script>
<script type="text/javascript">
    function CallService() {
        PollWSAsync.PollCastVote("1",
   Callback);
    }

    function Callback(result) {
        alert('CallBack Occured');
    }
</script>
<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <asp:ServiceReference Path="PollWSAsync.asmx" />
    </Services>
</asp:ScriptManager>
<asp:Button ID="btnVote" runat="server" Text="Vote" OnClientClick="CallService();return false;" />
Advertisements

One thought on “Calling Web Service (asmx) From JavaScript Using PageMethods

  1. Hello Derek,

    I have difficulty to RUN AN ASMX from Javascript. I have tried your methods as well and still not much luck. I can run javascript functions. But am not able to run the asmx file:

    Here is the script part of my HTML:

    function myFunction(a) {

    var xmlhttp;
    var c = a + “L”;
    ToolkitScriptManager1.AcceptReject.AccRej(handleResult);
    document.getElementById(c).innerHTML = a + ” Rescheduled”;
    return false;
    }

    function handleResult(result) {
    alert(result);
    }

    Javascript code does not get into my webservice at all. I have placed a breakpoint and could detect this.

    Any suggestions?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s