Four easy steps to implementing an ASP.NET AJAX Web Service
In this blog post I'm going to show you the four easy steps to implementing an ASP.NET AJAX Web Service:
- 1) Set-up a web service, this sample call invalidates any name beginning with the letter ‘a' (it is already taken), throws an exception for any name beginning with the letter ‘b' and validates all other names.
using System;
using System.Globalization;
using System.Web.Services;
namespace BlogDemo.Utility
{
/// <summary>
/// The BlogDemoService provides a sample web service to demonstrate AJAX client-side web service calls
/// </summary>
[WebService(Namespace = "http://syrinx.net/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
Make sure to remove the following comment marks è // [System.Web.Script.Services.ScriptService]
[System.Web.Script.Services.ScriptService]
public class BlogDemoService : WebService
{
[WebMethod]
public bool IsNameTaken(string checkName)
{
bool retVal = false;
if (checkName.StartsWith("a", true, CultureInfo.CurrentCulture))
{
retVal = true;
}
else if (checkName.StartsWith("b", true, CultureInfo.CurrentCulture))
{
throw new Exception("Names cannot start with either the letter 'B' or 'b'");
}
return retVal;
}
}
}
N.B.: The asmx file must have the fully qualified name (including namespace) :
<%@ WebService Language="C#" CodeBehind="~/App_Code/BlogDemoService.cs" Class="BlogDemo.Utility.BlogDemoService" %>
- 2) Add the ScriptManager control to the page like so:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/Services/BlogDemoService.asmx" />
</Services>
</asp:ScriptManager>
- 3) Add javascript to call the webservice - note that it requires a call to the fully qualified name
<script type="text/javascript">
function CheckNameAvailability(info)
{
var checkName = $get("txtUserName").value;
BlogDemo.Utility.BlogDemoService.IsNameTaken(checkName, OnCheckNameSuccess, OnCheckNameFailure, info);
}
function OnCheckNameSuccess(results, userContext, methodName)
{
alert("Success using method: " + methodName);
alert("This data was passed with the call: " + userContext);
if(results)
{
alert("Name is taken");
}
else
{
alert("Name is available");
}
}
function OnCheckNameFailure(exception, userContext, methodName)
{
alert("Failure using method: " + methodName);
alert("This data was passed with the call: " + userContext);
alert(exception._message);
}
</script>
The calls to and from the web service use the complete signature to the Web Service call. The signature for the call into the Web Service is:
FullyQualifiedWebService. WebMethod(parameters, successfulCallback, failedCallback, userContext);
The successful callback signature is: function successfulCallback(result, userContext, methodName) {}
The failed callback signature is: function failedCallback(exception,userContext,methodName) {}. The exception variable passed to the failedCallback is a JSON serialized Exception object, providing the description of the error and a full stack trace. This allows the developer to handle-and-re-throw exceptions on the server and still gracefully deal with them on the client.
The following web page shows how the information can be used - results are displayed using a simple alert as well as accessing a text box from the client side.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>AJAX Web Service Page</title>
<script type="text/javascript">
var txtResultsID = '<% =txtResults.ClientID %>';
function CheckNameAvailability(info)
{
var checkName = $get("txtUserName").value;
BlogDemo.Utility.BlogDemoService.IsNameTaken(checkName, OnCheckNameSuccess, OnCheckNameFailure, info);
}
function OnCheckNameSuccess(results, userContext, methodName)
{
alert("Success using method: " + methodName);
alert("This data was passed with the call: " + userContext);
if(results)
{
$get(txtResultsID).value = "Name is taken";
}
else
{
$get(txtResultsID).value = "Name is available";
}
}
function OnCheckNameFailure(exception, userContext, methodName)
{
alert("Failure using method: " + methodName);
alert("This data was passed with the call: " + userContext);
$get(txtResultsID).value = exception._message;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/Services/BlogDemoService.asmx" />
</Services>
</asp:ScriptManager>
<div>
<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox><br />
<asp:Button ID="btnSendBasicInfo" runat="server" Text="Send Basic" OnClientClick="CheckNameAvailability('Just the basics'); return false;" />
<asp:Button ID="btnSendMoreInfo" runat="server" Text="Send More" OnClientClick="CheckNameAvailability('Very detailed information'); return false;" /><br />
<asp:TextBox ID="txtResults" runat="server" Text="" Width="350px" ReadOnly="true"></asp:TextBox>
</div>
</form>
</body>
</html>
That's it for this time - hope you found it useful.