Extend ASP.NET AJAX Client-Side Function - The Server-Side Way
page 8 of 11
by Xianzhong Zhu
Feedback
Average Rating: 
Views (Total / Last 10 Days): 54141/ 155

Sample 2

In my opinion, to build a server-side ASP.NET AJAX control is even more complex than to build a client-side one. On the one hand, control developers must be familiar with the fundamentals to construct ASP.NET Server controls; on the other hand, they still have to grasp the client-side DOM, JavaScript, and ASP.NET AJAX client-side programming. Of course, they can be divided into two groups—one takes care of the server-side techniques while the other does the client-side ones. This means the whole process of developing a server-side ASP.NET AJAX control can be simplified. In real scenarios this is usually not the case. However, there are still many reasons to explorer the means to develop server-side ASP.NET AJAX controls. For example, the common web page developers can more easily and conveniently work with these controls using standard ASP.NET control syntax without worrying about writing custom JavaScript code or even using the ASP.NET AJAX script library’s $create() method to instantiate the controls.

Since we are to write a visual menu control from scratch that generates HTML and JavaScript, we will get the control derived from System.Web.UI.WebControl and implement the IScriptControl interface. And, at the same time, the menu control will continue to leverage the "AjaxMenuCtrl.js" client-side control script discussed in the earlier article "Explorer Ways to extend ASP.NET AJAX Client-side Function."

Author's Note: In this sample below, we will embed the related scripts in the server-side controls. Of course, you can also place the related resources used by the control assembly outside it. For details about this, you can refer to related topics in MSDN.

Creating a WebControl Class that Implements IScriptControl Interface

1. Start up Visual Studio 2005 and create a new WebControl library called AJAXServMenuLib.

2. Right-click the project and select "Add References…" to add a reference to the System.Web.Extensions.dll assembly. This is a must have because IScriptControl interface is defined within namespace "System.Web.UI" defined inside "System.Web.Extensions" namespace.

3. Add a new JavaScript file called AjaxMenuCtrl.js. Right click it and, in the Properties panel, set the Build Action property to "Embedded Resource."  In this way, the compiler can embed the file as an assembly resource that can be loaded in a web page.

4. To make the above script accessible, add the following assembly attribute immediately above the server control’s namespace definition.

[assembly: System.Web.UI.WebResource("AJAXServMenuLib.AjaxMenuCtrl.js""text/javascript")]
namespace AJAXServMenuLib
{……

This makes the script accessible through an HttpHandler built into ASP.NET AJAX called ScriptResource.axd and avoids having to deploy the physical script file along with the server control assembly, which can greatly simplify deployment and maintenance. The WebResource attribute’s constructor accepts the name of the resource followed by the content-type of the resource. Note that the name given to the resource is the assembly name followed by the name of the script.

5. Implement interface IScriptControl.

As is emphasized above, to make the server control ajaxified we should implement IScriptControl interface as follows:

Listing 9

public class AJAXServMenuCtrl: WebControl, IScriptControl
{
  //Properties and methods definitions…
  protected virtual IEnumerable < ScriptDescriptor > GetScriptDescriptors()
  {
    ScriptControlDescriptor descriptor = new ScriptControlDescriptor(
      "Samples.AjaxMenuCtrl", this.ClientID);
    descriptor.AddProperty("MenuTitle"this.MenuTitle);
    descriptor.AddProperty("MenuTopCssClass"this.MenuTopCssClass);
    descriptor.AddProperty("MenuListCssClass", this.MenuListCssClass);
    descriptor.AddProperty("ServicePath"this.ServicePath);
    descriptor.AddProperty("ServiceMethod"this.ServiceMethod);
    return new ScriptDescriptor[]
    {
      descriptor
    };
  }
 
  protected virtual IEnumerable < ScriptReference > GetScriptReferences()
  {
    ScriptReference r = new ScriptReference();
    r.Assembly = "AJAXServMenuLib";
    r.Name = "AJAXServMenuLib.AjaxMenuCtrl.js";
    return new ScriptReference[]
    {
      r
    };
  }
 
  IEnumerable < ScriptReference > IScriptControl.GetScriptReferences()
  {
    return GetScriptReferences();
  }
 
  IEnumerable < ScriptDescriptor > IScriptControl.GetScriptDescriptors()
  {
    return GetScriptDescriptors();
  }
}

Here, with two helper functions, GetScriptDescriptors and GetScriptReferences, we have implemented two methods declared inside interface IScriptControl.

The GetScriptReferences() method shown above creates a ScriptReference object and identifies the script resource that the server control needs to send to the client (AJAXServMenuLib.AjaxMenuCtrl.js, in this case). The GetScriptDescriptors() method creates a new ScriptControlDescriptor object that maps server-side control properties to client-side control properties. This is necessary so that the property values set on the control by a developer can be passed to the $create() method used to instantiate the client-side control. Note that the properties defined in this server-side control are quite the same ones discussed in my earlier article.

6. Overriding Render and OnPreRender

Once our custom AJAXServMenuCtrl control’s script resources are identified and server-side properties are mapped to client-side properties, the control should override the WebControl's OnPreRender method and retrieve a reference to the ScriptManager object in the page. The ScriptManager object is then used to register the AJAXServMenuCtrl control as a script control by calling the ScriptManager’s RegisterScriptControl() method.

Also, this server-side control should override the WebControl's Render method to register the property mappings (referred to as script descriptors) returned from the GetScriptDescriptors() method. This serves the purpose of passing the control’s property values defined on the server-side to the $create() method generated automatically by the ScriptManager control. Listing 10 shows the two methods.

Listing 10

protected override void OnPreRender(EventArgs e)
{
  if (!this.DesignMode)
  {
    _ScriptManager = ScriptManager.GetCurrent(Page);
    if (_ScriptManager == null)
      throw new HttpException(
        "A ScriptManager control is required in the page.");
    ScriptManager.RegisterScriptControl(this);
  }
  base.OnPreRender(e);
}
 
protected override void Render(HtmlTextWriter writer)
{
  if (!this.DesignMode)
  {
    _ScriptManager.RegisterScriptDescriptors(this);
  }
  base.Render(writer);
}

7. Build the project and generate the final assembly—AJAXServMenuLib.dll.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2019 ASPAlliance.com  |  Page Processed at 2019-08-25 2:19:32 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search