ASP.net - Ajax.Net: PageMethods

February 21, 2010 by C#   ASP.NET  

PageMethods in Ajax.net allow us to call server-side methods (e.g. C#, VB.net) from within client-side functions (e.g. JavaScript).

There is one limitation I would like to point out, before continuing with my post - the fact that one can't access webcontrols (e.g. GridViews, DropDownList), from within the server-side method we're calling.

Which is an obvious limitation; in regards to maintaining ViewState, ControlState, re-rendering of controls etc - since we're working with which is essentially dead objects. (We'd need to pass state to our method, rebuild our page with its various control collections re-instate it with our background request (Ajax), eventually altering the current page in view, including its various states - potentially defeating the whole purpose of what Ajax is all about, since we'd simply be recreating postbacks, not very effective)

Note: we can however access the rendered controls client-side using the DOM, which will be demonstrated in this post.

In this post, we're going to create a crude little web application, that's going to look something like this:



  • The user can delete an item from the listbox, by selecting/highlighting an item and pressing the delete key (on their keyboard) - via PageMethod
  • The user can add a new item to the lisbox - via PageMethod & demonstrating JSON (JavaScript object notation)

The first thing you need to do (within your framework 3.5 enabled web application/site), is add a scriptmanager to your page (or masterpage), set the EnablePageMethods property to true.

<asp:ScriptManager runat="server" ID="smAjax" EnablePageMethods="true"></asp:ScriptManager>

In order to make server-side methods callable, you'll need to define them as public static and mark them with the WebMethod attribute (which we generally use in webservices), notice the server-side method responsible for removing items from the database:

[WebMethod]
public static void delete_lbxFriends(Int32 friendID)
{
	using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString))
	{
		connection.Open();
		using (SqlCommand command = new SqlCommand("removeFriend", connection))
		{   
			command.CommandType = CommandType.StoredProcedure;
			command.Parameters.AddWithValue("@friendID", friendID);
			command.ExecuteNonQuery();
		}
	}
}

The client-side function (for deleting items) will look something like this:

function deleteListItem(sender, e) 
{
	if (e.keyCode == 46) {
		var friendID = sender.options[sender.selectedIndex].value;
		sender.disabled = true;
		PageMethods.delete_lbxFriends(friendID, succeededDeletedCallback, failedDeletedCallback, sender);
	}
}
  • The keyCode 46 represents the delete key - which we get from our triggered event
  • Variable "sender" contains our dropdown/listbox
  • The PageMethods object contains our callable server-side methods.
  • We disable the listbox while the server is busy processing our ajax request

Notice the function PageMethods.delete_lbxFriends, its first argument will be passed to our stored procedure, while the second and third arguments (succeededDeletedCallback and failedDeletedCallback) represents event handlers/callbacks, the last argument contains values (userContext) that gets passed to our callback functions - in this case I am passing the dropdown/listbox object to the callback functions.

The callback functions:

function succeededDeletedCallback(result, userContext, methodName) 
{
	userContext.remove(userContext.selectedIndex);
	userContext.disabled = false;
}
  • Remove the selected item from the dropdown/listbox
  • Re-enable listbox
function failedDeletedCallback(error, userContext, methodName) 
{
	if (error != null) {
		alert(error.get_message());
	}
	userContext.disabled = false;
}
  • Inform the user that something went wrong with their request
  • Re-enable the dropdown

This is how we attach the delete function to our listbox, don't be fooled by the fact that Visual Studio thinks that the onkeydown event doesn't exist - its definitely there ;)

<asp:ListBox runat="server" ID="lbxFriends" onkeydown="deleteListItem(this, event)"
	DataValueField="friendID" DataTextField="fullname"></asp:ListBox>

Lets have a quick look at adding an item to the listbox.

Our insert server-side method:

[WebMethod]
public static Object insert_lbxFriends(friend f)
{
	using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString))
	{
		connection.Open();
		using (SqlCommand command = new SqlCommand("addFriend", connection))
		{
			command.CommandType = CommandType.StoredProcedure;
			command.Parameters.AddWithValue("@firstname", f.firstname);
			command.Parameters.AddWithValue("@lastname", f.lastname);
			return command.ExecuteScalar();
		}
	}
}

// Basically the class needed for our JSON "action"
public class friend
{
	public String firstname { get; set; }
	public String lastname { get; set; }
}

The client-side function:

function addListItem() 
{
	// JSON
	var friend = 
	{
		firstname: $get("txtfirstname").value,
		lastname: $get("txtlastname").value
	};

	PageMethods.insert_lbxFriends(friend, succeededInsertedCallback, failedInsertedCallback, friend);
}

And only when our pagemethod completed successfully we add our new list item to the listbox, like seen in its callback function below.

function succeededInsertedCallback(result, userContext, methodName)
{
	var name = userContext.firstname + " " + userContext.lastname;
	$get("lbxFriends").options.add(new Option(name, result));
}

And that's the just of how to use PageMethods n Ajax.net, be sure to download the source code in the downloads section.


Leave a Comment




Related Downloads

Simple ASP.NET webforms page methods demo