static void

ASP AJAX Page method

UpdatePanel. WebService calls and the old ClientCallback have better documentation, but PageMethods are lean and easy. Here I return a string array for multiple pieces of data.
NB: for UpdatePanel, you can tell the postback by ScriptManager1.IsInAsyncPostBack (and the button/control that caused it in ScriptManager1.AsyncPostBackSourceElementID)

EnablePageMethods on ScriptManager

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

CodeBehind Static [WebMethod]

In the code behind, decorate the static method with WebMethod.


public static string[] GetServerData(string zip)


    ZipAddress u = respository.GetZipAddress(zip, GetTheme());

    if (u == null) throw new Exception("No zip found");

    return new string[] { u.City, u.State };


In this application, theme is used to partition the data by customer- so here's the hack to get Page.Theme.

private static string GetTheme()


    Configuration config = WebConfigurationManager.OpenWebConfiguration("~");

    PagesSection pagesSection =


    string theme = "";

    if (pagesSection != null)

        theme = pagesSection.Theme;

    return theme;


Client Side Code

In Javascript, call, arg2, onSuccess, onFail) and supply the two callbacks.

<asp:Button runat="server" ID="btnLookUp" Text="<%$ Resources: FindAddress %>" CausesValidation="false" UseSubmitBehavior="false" OnClientClick="FindAddress();//" />

<script type="text/javascript">

function FindAddress() {

    var zip = $get('<%= txtZip.ClientID %>');

    if(zip.value == '') return;

    PageMethods.GetServerData(zip.value, OnSucceeded, OnFailed);



function OnSucceeded(result, userContext, methodName)  {

    var city = $get('<%= txtCity.ClientID %>');

    var stae = $get('<%= txtState.ClientID %>');

    city.value = result[0];

    state.value = result[1];



function OnFailed(error, userContext, methodName) {




AutoComplete Extender

The ajaxtoolkit extender goes very well with page methods.

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="tk" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">

    <asp:TextBox runat="server" ID="txtLocation" />

    <tk:AutoCompleteExtender runat="server" ID="acLocation" TargetControlID="txtLocation" ServiceMethod="GetCompletionList" MinimumPrefixLength="1"  />

Code behind - use suitable data access



public static string[] GetCompletionList(string prefixText, int count)


    var locMgr = Respository.LocationManager;

    return locMgr.GetLocations(prefixText, count).ToArray();