WEBSITE

The ASP.NET AJAX Infrastructure : The Script Manager Control

10/10/2010 11:16:29 AM

The main control in the server infrastructure of ASP.NET AJAX is the ScriptManager control and its twin, the ScriptManagerProxy control. You will find just one instance of the ScriptManager control in each ASP.NET AJAX page. No AJAX capabilities can be enabled in ASP.NET pages that lack a reference to one ScriptManager control. The ScriptManagerProxy control is used only in master pages scenarios to reference the original script manager from content pages.

The ScriptManager control manages and delivers script resources, thus enabling client scripts to make use of the JavaScript type system extensions and other JavaScript features that we covered earlier in this chapter. The ScriptManager control also enables features such as partial-page rendering and Web service and page method calls. The following code shows the simplest and most common way to insert the script manager in an ASP.NET page:

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

The control produces no user interface, works exclusively on the server, and doesn’t add any extra bytes to the page download.

Properties of the ScriptManager Control

The ScriptManager control features a number of properties for you to configure its expected behavior. Table 1 details the supported properties.

Table 1. Properties of ScriptManager
PropertyDescription
AllowCustomErrorsRedirectIndicates whether custom error redirects will occur during an asynchronous postback. The property is set to true by default.
AsyncPostBackErrorMessageGets and sets the error message to be sent to the client when an unhandled exception occurs on the server during an asynchronous postback. If this property is not set, the native exception’s message will be used.
AsyncPostBackSourceElementIDGets the ID of the server control that triggered the asynchronous postback. If there’s no ongoing asynchronous postback, the property is set to the empty string.
AsyncPostBackTimeoutGets and sets the timeout period in seconds for asynchronous postbacks. A value of zero indicates no timeout. The property is set to 90 by default.
AuthenticationServiceGets an object through which you can set preferences for the client-side authentication service.
EnablePageMethodsIndicates whether static page methods on an ASP.NET page can be called from client script. The property is set to false by default.
EnablePartialRenderingIndicates whether partial rendering is enabled for the page. The property is set to true by default.
EnableScriptGlobalizationIndicates whether the ScriptManager control renders script in the client that supports parsing and formatting of culture-specific information. The property is set to false by default.
EnableScriptLocalizationIndicates whether the ScriptManager control retrieves script files for the current culture, if they exist. The property is set to false by default.
IsDebuggingEnabledIndicates whether the debug versions of client script libraries will be rendered. The debug attribute on the @Page directive doesn’t affect this property.
IsInAsyncPostBackIndicates whether the current page request is due to an asynchronous postback.
LoadScriptsBeforeUIIndicates whether scripts are loaded before or after markup for the page UI is loaded.
ProfileServiceGets an object through which you can set preferences for the client-side profile service.
RoleServiceGets an object through which you can set preferences for the client-side role service. This property is not available in ASP.NET AJAX Extensions for ASP.NET 2.0.
ScriptModeGets and sets the type (debug or retail) of scripts to load when more than one type is available. Possible values come from the ScriptMode enumeration type: Auto, Inherit, Debug, or Release. The default value is Auto, meaning that the type of script is determined on the fly.
ScriptPathIndicates that scripts should be loaded from this path instead of from assembly Web resources.
ScriptsGets a collection of script references that the ScriptManager control should include in the page.
ServicesGets a collection of service references that the ScriptManager control should include in the page.
SupportsPartialRenderingIndicates whether a particular browser or browser version can support partial page rendering. If this property is set to false, regardless of the value of the EnablePartialRendering property, no partial rendering will be supported on the page. The property is set to true by default.

The script manager is the nerve center of any ASP.NET AJAX pages and does all the work that is necessary to make AJAX features function as expected. Enabling AJAX features mostly means injecting the right piece of script in the right place. The script manager saves ASP.NET developers from dirtying their hands with JavaScript.

Methods of the ScriptManager Control

Table 2 lists the methods defined on the ScriptManager control.

Table 2. Methods of ScriptManager
MethodDescription
GetCurrentStatic method, returns the instance of the ScriptManager control active on the current page.
GetRegisteredArrayDeclarationStatic method, returns a read-only collection of ECMAScriptThis method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0. array declarations that were previously registered with the page.
GetRegisteredClientScriptBlocksStatic method, returns a read-only collection of client script blocks that were previously registered with the ScriptManagerThis method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0. control.
GetRegisteredDisposeScriptsStatic method, returns a read-only collection of dispose scripts that were previously registered with the page. This method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0.
GetRegisteredExpandoAttributesStatic method, returns a read-only collection of custom (expando) attributes that were previously registered with the page. This method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0.
GetRegisteredHiddenFieldsStatic method, returns a read-only collection of hidden fields that were previously registered with the page. This method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0.
GetRegisteredOnSubmitStatementsStatic method, returns a read-only collection of onsubmitThis method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0. statements that were previously registered with the page.
GetRegisteredStartupScriptsStatic method, returns a read-only collection of startup scripts that were previously registered with the page. This method is not available in ASP.NET AJAX Extensions for ASP.NET 2.0.
RegisterArrayDeclarationStatic method, ensures that an ECMAScript array is emitted in a partial rendering page.
RegisterAsyncPostBackControlTakes note that the specified control can trigger an asynchronous postback event from within an updatable panel.
RegisterClientScriptBlockStatic method, ensures that the specified script is emitted in a partial rendering page.
RegisterClientScriptIncludeStatic method, ensures that the markup to import an external script file through the src attribute of the <script> tag is emitted in a partial rendering page.
RegisterClientScriptResourceStatic method, ensures that the markup to import an external script from the page’s resources is emitted in a partial rendering page.
RegisterDataItemRegisters a string of data that will be sent to the client along with the output of a partially rendered page.
RegisterDisposeRegisters controls that require a client script to run at the end of an asynchronous postback to dispose of client resources.
RegisterExpandoAttributeStatic method, ensures that the markup to import a custom, nonstandard attribute is emitted in a partial rendering page.
RegisterExtenderControlRegisters an extender control with the current ASP.NET AJAX page.
RegisterHiddenFieldStatic method, ensures that the specified hidden field is emitted in a partial rendering page.
RegisterOnSubmitStatementStatic method, ensures that that client-side script associated with the form’s OnSubmit event is emitted in a partial rendering page.
RegisterPostBackControlTakes note that the specified control can trigger a full postback event from within an updatable panel.
RegisterScriptControlRegisters a script control with the current ASP.NET AJAX page.
RegisterScriptDescriptorsRegisters a script descriptor with the current ASP.NET AJAX page.
RegisterStartupScriptStatic method, ensures that client-side script is emitted at the end of the <form> tag in a partial rendering page. In this way, the script will execute as the page refresh is completed.
SetFocusAllows you to move the input focus to the specified client element after an asynchronous postback.

All static methods emit some form of script and markup in the client page. These static methods are the AJAX counterpart of similar methods defined on the page’s ClientScript object that you should know from ASP.NET 2.0. The static RegisterXXX methods on the ScriptManager class ensure that the given piece of script and markup is properly emitted only once in each partial update of the ASP.NET AJAX page. Similarly, other nonstatic RegisterXXX methods should be seen as tools to emit proper script code in ASP.NET AJAX pages—especially script code that is associated with custom controls.

Note

Script registration is an old feature of ASP.NET, in spite of the slight changes that occurred in the transition from version 1.x to 2.0. To most developers, script registration is a pretty neat and clear feature. However, the advent of ASP.NET AJAX extensions mixed things up a little bit. What’s the difference between RegisterXXX methods in the ScriptManager control and the page’s ClientScript object, which is an instance of the ClientScriptManager class?

ClientScriptManager’s and ScriptManager’s registration methods serve the same purpose but in radically different scenarios. You need to use the ScriptManager’s methods only if you need to emit script code during an AJAX partial rendering postback operation. An AJAX partial rendering postback operation is processed by the runtime as usual, except for the rendering stage. At this time, the markup is generated and any registered script is emitted. Because during AJAX postbacks the ScriptManager is responsible for the markup rendering, it’s the ScriptManager that needs to know about registered scripts to emit. If you stick to using ClientScriptMananager’s methods in an AJAX page, you risk that no script will be emitted during the refresh of an updatable panel. As a result, a portion of your page might display strange and weird behaviors.


Events of the ScriptManager Control

Table 3 details the two events fired by the ScriptManager control.

Table 3. Events of ScriptManager
EventDescription
AsyncPostBackErrorOccurs when an exception goes unhandled on the server during an asynchronous postback.
ResolveScriptReferenceOccurs when the ScriptManager control is going to resolve a script reference.

Both events are much more than mere notifications of something that has happened on the server. Both give you good chances to intervene effectively in the course of the application. For example, by handling the ResolveScriptReference event, you can change the location from where the script is going to be downloaded on the client:

protected void ResolveScript(object sender, ScriptReferenceEventArgs e)
{
// Check Path or Name on the e.Script object based on what you've put in Scripts.
// Next, you specify the real file to load
if (String.Equals(e.Script.Path, "personal.js", StringComparison.OrdinalIgnoreCase))
e.Script.Path = "person.js";
}



By handling the AsyncPostBackError event, you can edit the error message being returned to the client. Here’s an example:

protected void AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
ScriptManager sm = sender as ScriptManager;

if (Request.UserHostAddress == "127.0.0.1")
{
sm.AsyncPostBackErrorMessage = String.Format(
"<b>An error occurred. <br/>{0}<b>",
e.Exception.Message);
}
else
{
sm.AsyncPostBackErrorMessage = String.Format(
"<b>An error occurred. <br/>{0}<b>",
"Please contact your Web master.");
}
}



When executed locally, the client-side error message appears as you see in Figure 1.

Figure 1. An error occurred during a partial rendering operation

What if you don’t like to display the message directly in the page popups and want to redirect the user to an error page instead? In this case, you configure the page to use the traditional error-handling mechanism for ASP.NET pages. You configure the <customErrors> section in the web.config file and indicate HTML error pages to reach in case of specific errors. This behavior is fully supported by ASP.NET AJAX and can be disabled by setting to false the value of the AllowCustomErrorRedirects property of the ScriptManager object.

Note

When an exception is thrown during a partial rendering operation, the HTTP request returns a regular HTTP 200 status code, but instead of including the updated markup, it includes a full description of the error. In ASP.NET AJAX Extensions for ASP.NET 2.0, the default error handler pops up a client-side message box with the exception message or any text you assign to the AsyncPostBackErrorMessage property. In ASP.NET 3.5, on the other hand, you get a JavaScript exception.


The ScriptManagerProxy Control

Only one instance of the ScriptManager control can be added to an ASP.NET AJAX page. However, there are two ways in which you can do this. You can add it directly on the page using the <asp:ScriptManager> tag or indirectly by importing a component that already contains a script manager. Typically, you can accomplish the second alternative by importing a user control, creating a content page for a master page, or authoring a nested master page.

What if a content page needs to add a new script reference to the manager? In this case, you need a reference to the script manager. Although it’s defined in the master page (or in a user control), the script manager might not be publicly exposed to the content page. You can use the static method GetCurrent on the class ScriptManager to get the right instance:

// Retrieve the instance of the ScriptManager active on the page
sm = ScriptManager.GetCurrent(this.Page);

The ScriptManagerProxy class saves you from this sort of coding. In general, in cases where you need features of the ScriptManager control but lack a direct reference to it, you can instead include a ScriptManagerProxy control in the content page.

You can’t have two script managers in the context of the same page; however, you can have a script manager and a proxy to retrieve it. The ScriptManagerProxy control enables you to add scripts and services to nested components, and it enables partial page updates in user controls and nested master pages. When you use the proxy, the Scripts and Services collections on the ScriptManager and ScriptManagerProxy controls are merged at runtime.

Note

The ScriptManagerProxy class is a very simple wrapper around the GetCurrent method of the ScriptManager class, and its programming interface is not an exact clone of the ScriptManager. From within the proxy, you have access only to a limited number of properties, including Scripts, Services, AuthenticationService, RoleService, and ProfileService. If you need to modify anything else, refer to the GetCurrent static method of the ScriptManager class.


Script Binding and Loading

By extensively relying on client capabilities, ASP.NET AJAX requires a lot of script code. The framework itself links a lot of code, as do custom controls and actual user pages. The only HTML-supported way of linking script files is the <script> tag and its src attribute. The ScriptManager control can be used to save yourself the direct manipulation of quite a few <script> tags and also obtain richer features, such as built-in management of localized scripts.

You use the Scripts collection to tell the ScriptManager about the scripts you want to add to the page. The collection can be accessed either declaratively or programmatically. In addition to the user-requested scripts, the ScriptManager control automatically emits in the client page any ASP.NET AJAX required script. This means that, as a page developer, you don’t have to worry about linking the Microsoft AJAX library or any other ASP.NET AJAX native feature. The following example illustrates the script loading model you can use to load optional and custom scripts:

<asp:ScriptManager runat="server" ID="ScriptManager1">
<Scripts>
<asp:ScriptReference
Name="YourCompany.ScriptLibrary.CoolUI.js"
Assembly="YourCompany.ScriptLib" />
<asp:ScriptReference
Path="~/Scripts/MyLib.js" />
</Scripts>
</asp:ScriptManager>

Table 4 lists the properties of the ScriptReference class by means of which you can control the loading of scripts.

Table 4. Events of ScriptManager
PropertyDescription
AssemblyIndicates the assembly that contains in its resources the script to download on the client.
IgnoreScriptPathBoolean value, indicates whether the ScriptPath value optionally set at the top ScriptManager level has to be ignored. This property is set to false by default.
NameName of the script to download on the client.
NotifyScriptLoadedBoolean value, indicates whether the script resource loader should automatically append a script-loaded notification statement to let the Sys.Application object know when the script is loaded. This property is set to true by default.
PathIndicates the server path where the script to download on the client can be found.
ResourceUICulturesA comma-delimited string of valid user-interface cultures supported by the path.
ScriptModeSpecifies the algorithm for choosing between the debug and release versions of the script file. If no debug version exists, the ScriptReference class automatically falls back to release code. Feasible values for the property come from the ScriptMode enumeration type.

You can reference script files, including ASP.NET AJAX system scripts, either from an assembly or from a disk file. There’s a benefit in using disk files. You gain something in performance because less work is required to load the script in memory directly from a file. We’ll see how to reference from disk the principal ASP.NET AJAX script file—MicrosoftAjax.js—which alone contains two-thirds of the Microsoft AJAX library. The technique is also valid for any custom script file, however.

Normally, you don’t take care of MicrosoftAjax.js—you just find it downloaded care of the script manager. If you examine the HTML source of an ASP.NET AJAX page, you can hardly find a reference to such a file. Here’s what you find instead:

<script src="/Core35/ScriptResource.axd?d=...&amp;t=..."
type="text/javascript">
</script>

Script references obtained from embedded Web resources are served by the ScriptResource.axd HTTP handler. In ASP.NET AJAX, this handler replaces an old acquaintance, the WebResource.axd handler—a native component of ASP.NET 2.0. What’s the difference? In addition to serving script references, the ScriptResource.axd handler also appends any localized JavaScript resource types for the file.

To load a system file from disk, or to load a manually modified version of a system script file, you create a directory structure that roots under a custom folder the following subdirectories:

System.Web.Extensions\3.5.0.0

Now set the ScriptPath property on ScriptManager to a custom parent folder specific to your application. Say, you call it JS:

<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptPath="~/JS" />

All of a sudden, the MicrosoftAjax.js script file is now referenced as shown here:

<script
src="~/JS/System.Web.Extensions/3.5.0.0/MicrosoftAjax.js"
type="text/javascript">
</script>

Needless to say, your pages will fail if no such script files can be found in the specified directory path.

Handling Debug and Release Script Files

One of the additional free services offered by ScriptManager that isn’t offered by the classic <script> tag is the ability to automatically link debug or release script files, as appropriate. ASP.NET uses a special naming convention to distinguish between debug and release script files. Given a release script file named script.js, its debug version is expected to be filed as script.debug.js.

In general, the main difference between debug and release scripts is that the release scripts remove unnecessary blank characters, comments, trace statements, and assertions. Normally the burden of switching the links to debug and release scripts is left to the developer.

The ScriptManager control takes on this burden and, based on the aforementioned naming convention, distinguishes between debug and release scripts. The ScriptManager control picks debug scripts when the debug attribute of the <compilation> section in the web.config file is true.

Localized Scripts

Script files can have localizable elements such as text strings for messages and user-interface elements. When the EnableScriptLocalization property is set to true and a UI culture is properly set in the page, the script manager automatically retrieves script files for the current culture, if any.

Localization is driven by the UICulture attribute in the @Page directive and the UICulture property in the Page class:

<%@ Page Language="C#" UICulture="it-IT" ... %>

This information is not enough for the ScriptManager to pick up localized scripts, if any. You also need to specify which UI cultures you intend to support for each referenced script. You indicate the supported cultures through the ResourceUICultures property on individual script references. The property is a comma-separated string of culture symbols. Here’s an example:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnableScriptLocalization="true">
<Scripts>
<asp:ScriptReference Path="Person.js" ResourceUICultures="it-IT" />
</Scripts>
</asp:ScriptManager>



Note that ResourceUICultures is ignored if the Path attribute is not specified on the script reference tag.

At this point, if the page requires a script named person.js and the UI culture is set to it-IT, the ScriptManager object attempts to retrieve a script file named person.it-IT.js from the same path.

Script Globalization

Globalization is a programming feature that refers to the code’s ability to support multiple cultures. A request processed on the server has a number of ways to get and set the current culture settings. For example, you can use the Culture attribute on the @Page directive, the Culture property on the Page class, or perhaps the <globalization> section in the web.config file. How can you access the same information on the client from JavaScript?

When the EnableScriptGlobalization property is true, the ScriptManager emits proper script code that sets up a client-side global Sys.CultureInfo object that JavaScript classes can consume to display their contents in a culture-based way. Only a few methods and a few JavaScript objects support globalization. In particular, it will work for the localeFormat method of Date, String, and Number types. Custom JavaScript classes, though, can be made global by simply calling into these methods or accepting a Sys.CultureInfo object in their signatures.

Other  
 
Most View
Essential Mobile-Commerce Technology (part 2) - MOBILE COMMERCE SECURITY
Epson Expression Premium XP-605 - Comprehensive Printer
Creating Custom Workflows with SharePoint Designer 2010 (part 2) - Workflow Actions, Creating a Simple Workflow
Bin Your ISP Router (Part 6) : Netgear D6300, Netgear DGND4000
Nikon Coolpix L820 Super-Zoom Camera Review (Part 1)
Make The Switch (Part 1)
Samsung NX1000 - The Do It All Camera
How To Disable The Windows 8 Lock Screen
Solve Computer, Software, And Internet Problems (Part 3)
CrowdFunding - Does It Work? (Part 1)
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered