Microsoft AJAX Features and Implementation Samples


There are many options within the Microsoft stack of products for AJAX type functionality.  The following article covers the primary mechanisms that utilize the Microsoft out of the box Ajax functionality.  Ajax must be one of the technologies used in all current web applications.  The primary benefit is the improved user experience by providing quick, responsive feedback. Core features include Ajax Client Libraries and Ajax Server Controls.

- April 20, 2015

Rest of the Story:

There are many options within the Microsoft stack of products for AJAX type functionality.  The following article covers the primary mechanisms that utilize the Microsoft out of the box Ajax functionality.  Ajax must be one of the technologies used in all current web applications.  The primary benefit is the improved user experience by providing quick, responsive feedback.

Core features include Ajax Client Libraries and Ajax Server Controls.  These libraries and controls enable the developer to quickly implement solutions within any ASP.NET application. 
I have also included in this article the examples for utilizing the Microsoft AJAX libraries using:

  • update panel server control
  • access to web service from JavaScript
  • access to page methods (without web service)
  • HttpRequest/Post from javascript.

AJAX Client Libraries

  • Client-Script libraries that provide features for object-oriented development which enable high level of consistency and modularity in client scripting.

  • Browser compatibility

  • Extensions to JavaScript such as classes, namespaces, event handling, inheritance, data types and object serialization

  • Networking layer that handles communication with web based services

  • Sys Namespace

  • Javascript Shortcuts i.e. $get(‘elementId’), $addHandler, $removeHandler

Asp.Net AJAX Server Controls

  • ScriptManager

  • Manages Javascript

  • Enables partial page rendering w/UpdatePanel

  • Creates client side proxies for Web Services

  • Provides registration methods for scripts

<asp:ScriptManager ID="mng1" runat="server"  
                    EnablePartialRendering="true|false"  
                    EnablePageMethods="true|false"  
                    ScriptMode="Auto|Inherit|Debug|Release"  
                    ScriptPath="...">                          
                    <Scripts>  
                        <asp:ScriptReference Name="script.js" Assembly="..." />  
                    </Scripts>  
                    <Services>  
                        <asp:ServiceReference Path="~/MyWebService.asmx" />                          
                    </Services>      
       </asp:ScriptManager>
  • ScriptManagerProxy

  • Used with Master Pages

  • If you include the ScriptManager control on the master page, it can act as the ScriptManager control for all content pages.  If you want to register scripts or services declaratively in a content page, you can add a ScriptManagerProxy control to the content page.

  • UpdatePanel

  • Improves user experience of application by updating a portion of the web page thereby improving interactivity

  • By default controls within the update panel can trigger the update.  ChildrenAsTriggers property is by default set to true.  In our example the link button is within the update panel and so can trigger the partial page update.  By default any postback control inside an update panel causes an async postback

  • Controls outside of the update panel can also trigger the panel contents to update.  For example look at btnGo, it resides outside the panel however it is defined within the panel as a trigger/control that can force the async update to the panel contents.  Reference the <asp:AsyncPostBackTrigger> element within the <Trigger> element of the updatePanel

  • set EnableParitalPageRendering=”true”

  • Shown here is how a timer defined outside of the panel can trigger the update panel to refresh at a defined interval

     <asp:UpdatePanel id=”panel1” runat=”server”                              UpdateMode=”Always/Conditional”                              ChildrenAsTriggers=”true/false”>                       <Triggers>                             <asp:AsyncPostBackTrigger ControlID=”timer1”/>                        </Triggers>                        <ContentTemplate>                             <!—page content here -->                       </ContentTemplate>        </asp:UpdatePanel>       <asp:Timer id=”timer1” runat=”server” Interval=”3000” OnTick=”OnTimerTick”/>
  • UpdateProgress

  • provides status information about partial-page updates in the UpdatePanel controls.  The content can be customized.  To prevent flashing when a partial-page update is very fast, you can specify a delay before the UpdatePanel control is displayed

Update Panel Example
Code behind which responds to the button click to update a label control with the current time.
public partial class Panel : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        lblName.Text = DateTime.Now.ToString();
    }
 
    protected void lnkButton_Click(object sender, EventArgs e) {
        lblName.Text = DateTime.Now.ToString();
    }
}
Page HTML code with embedded update panel which responds to a control within the panel and a button defined as a trigger outside of the panel control.
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                 <asp:Label ID="lblName" runat="server" CssClass="lbl" Text=""></asp:Label>
                 <asp:LinkButton ID="lnkButton" runat="server" CssClass="lnk" onclick="lnkButton_Click" Text="Update"></asp:LinkButton>
            </ContentTemplate>        
            <Triggers> 
              <asp:AsyncPostBackTrigger ControlID="btnGo" />
            </Triggers>
        </asp:UpdatePanel>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
            <ProgressTemplate>
                Updating.
            </ProgressTemplate>
        </asp:UpdateProgress>
        <br />
        <br />
        <asp:Button ID="btnGo" runat="server" CssClass="btn" Text="Go" />
    </form>
</body>
Ajax and Web Service Example
  • Script Callable Web Service
  • Proxies are automatically generated
  • [ScriptService] Attribute
  • If the web service returns a complex type, the succeeded callback function receives a return value in the form of Javascript object that corresponds to the server type.

Web Service code (simple function that returns ‘Hello World’)

  • Web Service has [ScriptService] attribute
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class MyWebService : System.Web.Services.WebService {
    public MyWebService () {
    }
 
    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }    
}
Page Code (page with button which calls js function, which in turn calls the web service defined within ScriptManager-ScriptReference tag)
<form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <asp:ServiceReference Path="~/MyWebService.asmx" />
        </Services>        
    </asp:ScriptManager>
    <asp:Button ID="btnGet" runat="server" CssClass="btn" Text="Get" OnClientClick="update();return false" />
    <script type="text/javascript">
 
        function update() {
            MyWebService.HelloWorld(onCompleted, onFailed);
        }
 
        function onCompleted(result, context, methodName) {
            alert(result);
        }
 
        function onFailed(err, context, methodName) {
            alert(err.get_message());
        }
    </script>
 
</form>
dy>
ml>
 
Page Method Example
  • Allows javascript Ajax call back to page without web service
  • use EnablePageMethods=true in the ScriptManager control
The following is a sample showing a code behind static method marked with WebMethod attribute.
public partial class PageMethod : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(DateTime.Now.ToString());
    }
 
    [System.Web.Services.WebMethod]
    public static string update(string input){
        return input.ToUpper();
    }
}
Aspx code with a button that calls javascript, which in turn calls the page method ‘update’ to return uppercase string.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" EnablePageMethods="true" />
    <asp:Button ID="btnGet" runat="server" CssClass="btn" Text="Get" OnClientClick="update();return false" />
 
        <script type="text/javascript">
   1:  
   2:             function update() {
   3:                 PageMethods.update("test", onCompleted);
   4:                 return false;
   5:             }
   6:             function onCompleted(result) {
   7:                 alert(result.toString());
   8:             }
   9:         
</script>
    </form>
</body>
</html>
  HTTP Requests (from Javascript) Sample
  • The async communication layer enables javascript to make a request over the network to any http end point by using Sys.Net.WebRequest class
  • The sample performs a post and get http request from javascript
Page code that initiates the javascript call GetWebRequest().
<form id="form1" runat="server">
 
<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/connect.js" />
    </Scripts>
</asp:ScriptManager>
 
<asp:Button ID="btnGo" runat="server" CssClass="btn" Text="GetWebRequest"  OnClientClick="GetWebRequest();return false;" />
<asp:Button ID="btnPost" runat="server" CssClass="btn" Text="PostWebRequest" OnClientClick="PostWebRequest();return false;" />
 
<div id="result">initial content</div>
 
 
</form>
Javascript (connect.js) file which performs the webrequest
// connect.js
 
var resultElement;
 
function pageLoad() {
    resultElement = $get("result");    
}
 
function GetWebRequest() {
    alert("performing web request");
    // Instantiate a WebRequest.
    var wRequest = new Sys.Net.WebRequest();
    // Set the request URL.      
    wRequest.set_url("getTarget.htm");
    alert("Target Url: getTarget.htm");
 
    // Set the request verb.
    wRequest.set_httpVerb("GET");
    // Set the request callback function.
    wRequest.add_completed(OnWebRequestCompleted);
    // Clear the results area.
    resultElement.innerHTML = "";
 
    // Execute the request.
    wRequest.invoke();      
}
 
// This function performs a POST Web request.
function PostWebRequest() {
    alert("Performing Post Web request.");
 
    // Instantiate a WebRequest.
    var wRequest = new Sys.Net.WebRequest();
 
    // Set the request URL.      
    wRequest.set_url("postTarget.aspx");
    alert("Target Url: postTarget.aspx");
 
    // Set the request verb.
    wRequest.set_httpVerb("POST");
 
    // Set the request handler.
    wRequest.add_completed(OnWebRequestCompleted);
 
    // Set the body for he POST.
    var requestBody =
        "Message=Hello! Do you hear me?";
    wRequest.set_body(requestBody);
    wRequest.get_headers()["Content-Length"] =
        requestBody.length;
 
    // Clear the results area.
    resultElement.innerHTML = "";
 
    // Execute the request.
    wRequest.invoke();
}
 
 
// This callback function processes the 
// request return values. It is called asynchronously 
// by the current executor.
function OnWebRequestCompleted(executor, eventArgs) {
    if (executor.get_responseAvailable()) {
        // Clear the previous results. 
        resultElement.innerHTML = "";
 
        // Display Web request status. 
        resultElement.innerHTML +=
          "Status: [" + executor.get_statusCode() + " " +
                    executor.get_statusText() + "]" + "<br/>";
 
        // Display Web request headers.
        resultElement.innerHTML += "Headers: ";
        resultElement.innerHTML += executor.getAllResponseHeaders() + "<br/>";
 
        // Display Web request body.
        resultElement.innerHTML +="Body:";
 
        if (document.all)
            resultElement.innerText += executor.get_responseData();
        else
            resultElement.textContent += executor.get_responseData();
    }
 
}
if (typeof (Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
Target Html file used in the Get
<!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>
    <title>Hello Page</title>
</head>
<body>
    <p> 
        Hello there. 
        I got your GET Web request!
    </p>
</body>
</html>
Post Aspx Page
<%@ Page Language="C#" AutoEventWireup="true"  %>
 
<!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>Post Target</title>
    <script language="C#" runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.Form["Message"] != null)
                LabelID.Text = 
                    HttpContext.Current.Request.Form["Message"].ToString();
        }
    </script>
 
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>WebRequestPost Target</h1>
        <p>
            <asp:Textbox id="LabelID"  
                Text="test" runat="server"/>
        </p>
        Yes, I got your POST Web request!
    </div>
    </form>
</body>
</html>