Use ClientScriptProxy for embedding JavaScript, Resources and CSS

ASP.NET's Web Form interface provides for the abililty to embed JavaScript, Web Resources and other content into the current page. As of Version 3.5 of .NET there are two mechanisms available to do so: Page.ClientScript and ScriptManager the latter of which is part of the ASP.NET AJAX. The ClientScriptProxy class bridges these two somewhat disparate technologies with a single front end interface. It also provides a few features that the base interfaces do not provide like the ability to embed scripts into the page header rather in two locations in addition to embedding scripts inline in the document as ClientScript and ScriptManager do.

Basic Usage of ClientScriptProxy: ClientScriptProxy.Current

ClientScript Proxy is a Singleton implementation and you can access it from anywhere using the static .Current property:

ClientScriptProxy.Current.RegisterClientScriptInclude(this.Page, typeof(ControlResources),
                                                      "~/scripts/jquery.js",
                                                      ScriptRenderModes.HeaderTop);

The syntax for most of the methods mirror that of the MS AJAX script manager. Most methods require a control and type as input just as ScriptManager does. These values are used as (rather unobvious) uniqueness constraints as well as a hint on where to find WebResources. Note that if you want to uniquely embed scripts or resources into the page use this.Page and a consistent type (I like to use typeof(ControlResources)) which ensures only a single link is embedded regardless how many times a method is called.

The following sections demonstrate some of the features of the ClientScriptProxy. Note that most of the methods have a few overloads. Please check the documentation for the ClientScriptProxy Class for more detailed method information.

Embedding JavaScript into the Page

Embedding a Script Link from a JavaScript File
To dynamically embed a link in the page from code you use the RegisterClientScriptInclude method which accepts a virtual path or full Url to a script file:

ClientScriptProxy.Current.RegisterClientScriptInclude(this.Page, typeof(ControlResources),
                                                      "~/scripts/jquery.js",
                                                      ScriptRenderModes.HeaderTop);

Note the path can be either virtual or a fully qualified URL starting with http:// or https:// to support external script references.

Embedding a JavaScript link from a WebResource
Embedding a resource from script code is a common thing to do for control developers. The RegisterClientScriptResource method supports ScriptManager syntax plus a couple of overloads that allow for specifying where script is embedded.

ClientScriptProxy.Current.RegisterClientScriptResource(this.Page, typeof(ControlResources),
                                                      "Westwind.Web.Controls.Resources.jquery.js",
                                                      ScriptRenderModes.HeaderTop);                
ClientScriptProxy.Current.RegisterClientScriptResource(this.Page, typeof(ControlResources),
                                                      "Westwind.Web.Controls.Resources.ww.jquery.js",
                                                      ScriptRenderModes.Header);

Note that the type parameter should point at a type that lives in the same assembly as the resource you're trying to retrieve.

Embedding a Block JavaScript Text
In some situations you may have to embed a block of script code into the page. To embed script into the page there are two mechanisms available that determine into which part of the page the script is embedded. RegisterClientScriptBlock embeds at the top of the page meaning it executes first. RegisterStartupScript is embedded at the bottom of the Page which means executes last. Typically RegisterClientScriptBlock is used to register global variables or functions, which RegisterStartupScript is used to embed code that is to execute when the page loads.

Embedding Global Script Block:

this.ClientScriptProxy.RegisterClientScriptBlock(this, this.GetType(), "_Callback_ErrorMessage",
                            "function showError(msg) { showStatus(msg ) };", true);

Embedding Startup Script (embedded at bottom of page):

this.ClientScriptProxy.RegisterStartupScript(this, this.GetType(), "_modalDialog_Startup",
                            "$('#" + this.ClientID + "').show();", true);

**Use jQuery's $().ready() Handler for Startup Code** RegisterStartupScript fires at the end of the Page, but there's no guarantee that the page has finished loading and all scripts are available. It's recommended that all startup code is fired of window.onload or preferrably of jQuery's ready handler.
this.ClientScriptProxy.RegisterStartupScript(this, this.GetType(), "_modalDialog_Startup",
                            "$().ready( function() { $('#" + this.ClientID + "').show(); }", true);

Using the ready() handler ensures that script executes after the DOM has completed loading and all script includes have been loaded.

A simpler version for embedding control specific script: LoadControlScript For Control developers there's a slightly simpler version of scripting available using the LoadControl method which automatically picks up ScriptLocation and/or resource name and based on that calls the appropriate method. This makes it easier to map control properties to a single method that handles both scripts and web resources.

this.ClientScriptProxy.LoadControlScript(this, this.jQueryScriptLocation, ControlResources.JQUERY_SCRIPT_RESOURCE, ScriptRenderModes.HeaderTop);

This method can accept WEBRESOURCE as the script location and if so use a resource. Otherwise the ScriptLocation is assumbed to be a script location Url or virtual path. This makes it easy for controls that have a default Web Resource Url but allow the user to override the location..

Embedding a CSS Link or WebResource into the page

Unlike ClientScript and ScriptManager you can also embed a CSS link into the page using the RegisterCssLink method:

ClientScriptProxy.Current.RegisterCssLink(this.Page, typeof(ControlResources), "_datepickerCss", "~/css/datepicker.css");

To load up CSS links from a WebResource use:

ClientScriptProxy.Current.RegisterCssResource(this.Page, typeof(ControlResources),"Westwind.Web.Controls.ui.datepicker.css");

CSS Resources are embedded at the end of the Html header in the page and are added in the order that they are declared.

Retrieving a Web Resource Url

WebResources are an important part of control development to allow creating self contained controls that contain their own resources and require no external file dependencies. WebResources can be embedded into the current assembly and be retrieved from there. The process of adding WebResources involves creating a resource in your assembly. For example to embed some script code as a resource you would:

Create your script file in a known location like off the project root like Resources in a file called jquery.js. You'd then mark this file as an Embedded Resource in the file properties.

Once the resource is embedded you need to expose it as a Web Resource by using the [assembly: WebResource] attribute to declare it:

[assembly: WebResource("Westwind.Web.Controls.Resources.jquery.js", "application/x-javascript")]

The name of the resource is the default namespace of the assembly (Westwind.Web.Controls) plus the path (Resources) plus the name of the file. Note that case is important! Once this is all in place the reosurce will be compiled into the assembly and available through GetWebResourceUrl:

ClientScriptProxy.Current.GetWebResourceUrl(this, this.GetType(), "Westwind.Web.Controls.Resource.jquery.js");

Note that the type parameter should point at a type that lives in the same assembly as the resource you're trying to retrieve.

Registering a Hidden Field

You can also register a hidden field into the page via code. This has little to do with scripts and resources, but it's part of the ScriptManager and ClientScript APIs and so exposed here as well.

ClientScriptProxy.Current.RegisterHiddenField(this,"_hiddenVar","invisble");

See also

Class ClientScriptProxy

© West Wind Technologies, 1996-2016 • Updated: 12/19/15
Comment or report problem with topic