Introduction
Hi! My name is Praveen Yerneni and I am a Technical Lead working
with the ASP.NET support group at Microsoft. In this month's column, I am
going to discuss Web Resources and how to implement them in your
application.
If you are a developer who works extensively with COM controls, you might find this article useful in addressing some of the key
issues that you may face while developing controls. Previously, in Microsoft ASP.NET 1.1, if you
wanted to deploy static files such as .html files, .css files, image files, and script files by using a
COM control, you had to create an installer and bundle these files together with the
COM control. Although this worked, it presented many problems while
deploying the control. For example, you may have had problems with version conflicts, with making sure that files such as
images were deployed to the same location, or with corrupted or deleted static files that could cause the control to fail.
Web Resources in
Microsoft ASP.NET 2.0 addresses these issues by letting the developer embed these
resources in the assembly as .resources. To access these static
resources, you can just call a method in the control's code.
You can download the sample code in this article from the Microsoft Download Center.
The following files are available for download from the Microsoft
Download Center:
For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to obtain Microsoft support files from online services
Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.
How Web Resources work
Web Resources rely on a special handler that is named WebResource.axd, which is designed to retrieve assembly resources and serve them
to the Web browser. The handler type for WebResource.axd is
AssemblyResourceLoader.
When a request comes in from the client for
WebResource.axd, the handler looks for the Web Resource identifier in the
QueryString method of the
Request object. Based on the value of the Web Resource identifier, the handler then tries to load the assembly that
contains this resource. If this operation is successful, the handler will then look for
the assembly attribute and load the resource stream from the assembly. Finally,
the handler will grab the data from the resource stream and send it to the client together with the content type that you
specify in the assembly attribute.
The URL for WebResource.axd looks like the following:
WebResource.axd?d=SbXSD3uTnhYsK4gMD8fL84_mHPC5jJ7lfdnr1_WtsftZiUOZ6IXYG8QCXW86UizF0&t=632768953157700078
The format of this URL is WebResource.axd?d=
encrypted
identifier&t=
time stamp value. The "d" stands for the
requested Web Resource. The "t" is the timestamp for the requested assembly,
which can help in determining if there have been any changes to the resource.
Delving into the code
In my example, I have developed a COM control that is consumed
by an ASP.NET Web application to demonstrate this new feature.
COM control for the Web Resource
For creating and embedding a Web Resource, I have developed a
COM control (
SimpleControl). It has the
following embedded resources:
- Two image files that are named smallFail.gif and smallSuccess.gif.
These image files are used for rollover effects in the control and are consumed
within the control code.
- An HTML file that is named Help.htm. This file does not contain much text and is just for demonstration.
- One JavaScript file that is named MyScript.js. This file
contains some JavaScript code which also demonstrates the substitution feature
to get a reference to another embedded resource within the same
assembly.
- One .css file that is named MyStyleSheet.css. This style
sheet is then consumed directly from the ASP.NET Web application.
In this article, I will discuss the parts
that are required for Web Resources.Embedding the Web ResourcesFirst, you have to make sure that all the static files
that are added to the Web Control Library project in Microsoft Visual Studio 2005 are embedded
resources. To embed these resources, all that you have to do is add these
files to Visual Studio and then modify the properties of these files so that the build action is set to
Embedded Resource.
After you have done this, you also have to make sure that these
resources have been referenced by the
WebResource assembly attribute in the AssemblyInfo.cs file as shown below.
[assembly: WebResource("SimpleControl.Help.htm", "text/html")]
[assembly: WebResource("SimpleControl.MyStyleSheet.css", "text/css")]
[assembly: WebResource("SimpleControl.smallFail.gif", "image/gif")]
[assembly: WebResource("SimpleControl.smallSuccess.gif", "image/gif")]
[assembly: WebResource("SimpleControl.MyScript.js", "text/javascript", PerformSubstitution = true)]
The
WebResource assembly attribute has three parameters as follows:
- Web Resource: The name of the resource that is embedded in the assembly
- ContentType: The MIME file type for the resource
- PerformSubstitution: A Boolean value that determines whether other Web Resource
URLs that are referenced in this resource are parsed and replaced with the full path of
the resource
Fetching the Web ResourcesFor getting the Web Resource, I have used the
GetWebResourceUrl method, which is a method of the
ClientScriptManager class that is typically used for managing client-side scripts. This method
returns a URL reference to the server-side resource that is embedded in an assembly. The
GetWebResourceUrl method accepts the following two parameters:
- Type: The type of the server-side resource
- Resource Name: The name of the server-side resource
To use this method, first you have to create an instance
of the
ClientScriptManager class and get the type of the class as shown below.
ClientScriptManager cs = Page.ClientScript;
Type rsType = this.GetType();
When you have an instance of this class, you then have to call this method
and pass the appropriate parameters as shown below, where I create a
HyperLink
button, and set the
NavigateURL method to point to an embedded HTML resource.
HyperLink hlHelpFile = new HyperLink();
hlHelpFile.NavigateUrl = cs.GetWebResourceUrl(rsType, "SimpleControl.Help.htm");
hlHelpFile.Attributes.Add("onmouseover", "ChangeImage('image1','Red')");
hlHelpFile.Attributes.Add("onmouseout", "RollbackImage('image1','Green')");
this.Controls.Add(hlHelpFile);
Image imgTest = new Image();
imgTest.ImageUrl = cs.GetWebResourceUrl(rsType, "SimpleControl.smallFail.gif");
imgTest.ID = "image1";
hlHelpFile.Controls.Add(imgTest);
Also in the same code listing above, I have created an
Image button and
the
ImageUrl attribute is getting its value from another embedded .gif image
resource.Using the Substitution featureAnother useful feature of using Web Resources is the
PerformSubstitution property of the
WebResource attribute as shown in the
"Embedding the Web Resources" section above. This feature lets you actually get Web Resources inside another embedded resource. If this property is enabled, the
WebResource handler will parse the embedded resource and replace the syntax for
the
WebResource assembly attribute with actual resources before serving the page.
In the code above, you will notice that the
HyperLink control has a client-side event that is named
ChangeImage. This
ChangeImage function is
located in a script file. The following is the code for this script.
function ChangeImage(imgControl,varcolor){
document.getElementById(imgControl).src = '<%= WebResource("SimpleControl.smallSuccess.gif")%>';
document.getElementById('Label1').style.color = varcolor;
}
function RollbackImage(imgControl, varcolor){
document.getElementById(imgControl).src = '<%= WebResource("SimpleControl.smallFail.gif")%>';
document.getElementById('Label1').style.color = varcolor;
}
This script file that is named MyScript.js is also an embedded resource in
the same COM control. And notice that I am using the
WebResource method to refer to another embedded resource in the script
file.
Also, to make sure that this JavaScript file is registered in
the page, I use the
RegisterClientScriptInclude method of the
ClientScriptManager class as shown below.
cs.RegisterClientScriptInclude("MyScript", cs.GetWebResourceUrl(rsType, "SimpleControl.MyScript.js"));
Consuming the control in ASP.NET
Once you have built the COM control successfully, you need to
consume this control in a client ASP.NET project. To do this, you just
have to add the control to the toolbox in ASP.NET. Then you can add the
control to any Web form in the designer.
When you add the control to the toolbox, the control is registered for you and the following code is added when you look at the HTML syntax.
<cc1:MSButton ID="MSButton1" runat="server" strText="Problems?"></cc1:MSButton>
In my COM control, I have also embedded a style sheet file, which I
will be using in my ASP.NET application. To access this style sheet, you
have to add a link
HtmlControl in the HTML page and set the
runat property to
server as
shown below.
<link rel="Stylesheet" id="lnkStyle" runat="server" />
After this, you can programmatically set the
Href attribute of this
control to point to the
WebResource assembly attribute in the
Page_Load event as shown below.
protected void Page_Load(object sender, EventArgs e)
{
//Get the name of the Web Resource.
String rsname = "SimpleControl.MyStyleSheet.css";
//Get the type of the class.
Type rstype = typeof(SimpleControl.MSButton);
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
lnkStyle.Href = cs.GetWebResourceUrl(rstype, rsname);
}
When you run the code, you will see a control that looks like the
following:
And on
mouse-over, the control will look like the following:
When you
click this link, it will take you to the help page, which is embedded in
the COM control assembly file.
Conclusion
Web Resources is a useful new feature in ASP.NET 2.0. You can use
this feature to your advantage if you use it wisely. Many caching techniques
have been used to make sure that Web Resources do not affect the performance of
the application.
In ASP.NET 2.0, WebResource.axd is used internally by
the Microsoft .NET Framework to retrieve embedded resources. For example, the .NET Framework uses WebResource.axd to retrieve the WebUIValidation.js script file that is used for
Validation controls and to retrieve the Menu.js script file for
Menu controls.
References
For more information, visit the following Microsoft Web sites:
For more information about Web Resources, see the following blogs by Nikhil Kothari: