Introduction
The custom controls that you develop not only contain the logic and data but also things such as images and JavaScript files. One easy way to make these images and script files available to your control at run time is to deploy them along with your control. This approach, though easy, is error prone. What if somebody deletes the images after the deployment? What if someone replaces the script files with malicious script? The best way is to embed such files in your control assembly itself and retrieve them in your code. Formally such files (images, script, multilingual strings etc.) are called as Resources. In this article we are going to learn various approaches taken to embed and retrieve resources in a custom control.
Embedding resources in a custom control
There are two ways to embed resources in a custom control:
- Using a resource file
- Directly
Resource files are actually XML files with extension of .resx. At compile time they get embedded in the assembly being compiled. You can retrieve them at run time in your code.
In order to add a resource to a resource file you first need to add a resource file to your web site. They you can add resources of the following types:
- Strings
- Images
- Icons
- Audio
- Files
For may of the above types VS.NET allows you to either create a new resource or add existing resource.
You can also embed files directly in the assembly by setting its Build Action to" Embedded Resource". Figure 1 shows the VS.NET property window for an image file with this option.
Figure 1: Build Action property of a file
Example 1 - Adding and retrieving a resource from resource file
Create a new project in VS.NET of type "Web Control Library". Right click on the project and choose "Add > New Item...". Select "Resource File" and give the name of the file as Resource1.resx. Double click on Resource1.resx to open the resource editor. Add a string resource with name as "myclientfunction". Add a small JavaScript function as the value of the above resource string. The JavaScript function looks as shown below:
function DisplayMsg()
{
alert("Hello World");
}
Double click on the web control class and override its Render method as shown below:
public class WebCustomControl3 : WebControl
{
protected override void Render(HtmlTextWriter output)
{
ResourceManager m=new ResourceManager
("WebResourceDemo.Resource1",
typeof(WebCustomControl3).Assembly);
output.Write("");
output.Write("name='button1' OnClick='DisplayMsg();'>");
}
}
We created an instance of System.Resources.ResourceManager class by passing two parameters in its constructor - the resource that we want to work with and the assembly in which the resource is embedded. Note that the fully qualified name of your resource is
Once you have resource manager ready with you then you can retrieve various resources from the resource file. In order to retrieve string resources you will use GetString() method of the ResourceManager class by passing the resource name (mycliebtname in our case) to it.
We finally emit an tag of type button and set its OnClick attribute to our JavaScript function name. This way when the user clicks on the button DisplayMsg() function will be called.
In order to test our control, add a new web site in the same solution. Open the Toolbox and drag and drop the control (it will appear towards the top of the Toolbox as shown in Figure 2
Figure 2: Custom web controls being displayed on the toolbox
If you wish you can manually add the control on the toolbox by right clicking on the toolbox and selecting "Choose items...".
Drag and drop our control on a web form and run. You should see something as shown in Figure 3.
Figure 3: Sample run of our control
The [WebResource] attribute
Though the above approach works well for multilingual strings, logos and images; it has one flaw. Imagine a case where you have a .JS file containing lot of reusable JavaScript functions. You want to use many of these functions in your custom control. As per above approach you need to add many separate string resources and retrieve them in your code. This may become complex if there are hundreds of functions in the file. Take another example, imagine that you are developing a custom image control inheriting from inbuilt Image web control and want to display image that is embedded in the assembly. That means somewhere in your code you need to set ImageUrl property to the URL of the image. But in this case there is no specific URL as such because the image is embedded in the assembly and does not have independent existence.
To tackle such problems ASP.NET 2.0 provides a great mechanism via an attribute called [WebResource]. The [WebResource] attribute essentially makes your embedded resources URL accessible. It is an assembly level attribute and takes two parameters:
- Fully qualified name of the embedded resource
- Content type such as "text/javascript", "image/gif" etc.
Now that we know what [WebResource] attribute is, let's see it in action.
Linking resources using [WebResource] attribute
Add a new web control class to the same project. Also, add a new JavaScript file called JScript1.js and write the DisplayMsg() function inside the file. Set the "Build Action" for this file to "Embedded Resource" (see Figure 1).
Open the AssemblyInfo.cs file of the project and add the [WebResource] attribute as shown below:
[assembly:WebResource
("WebResourceDemo.JScript1.js","text/javascript")]
Note the way we specified the fully qualified name of the JavaScript file. Since the file is a script file we set its content type to "text/javascript".
What we would like to do is - when the control is rendered on the page it should generate the following markup in addition to the control markup.
Since our JavaScript file is embedded inside the control assembly we can not provide any URL to it directly in the Render() method. That is where we will add some code to make our JavaScript file URL accessible. See the following code
protected override void Render(HtmlTextWriter output)
{
output.WriteBeginTag("script");
output.WriteAttribute("src",this.Page.ClientScript.
GetWebResourceUrl(typeof(WebCustomControl1),
"WebResourceAttbDemo.JScript1.js"));
output.Write(">");
output.WriteEndTag("script");
output.Write("name='button1' OnClick='DisplayMsg();'>");
}
In order to get URL accessible equivalent of the embedded resource we used a function of the ClientScript object of the Page class called called GetWebResourceUrl(). The URL returned by this method will look something as shown below:
Note how ASP.NET adds a link to WebResource.axd tool. This tool internally grabs the resource embedded in the assembly and returns to the client.
To test the [WebResource] attribute, add a new web form in the web site we developed previously. Drag and drop the new control on it and run the web form. The output should be identical to Figure 3. View the HTML source of the page and observe the
![]()




0 comments:
Post a Comment