Tag Libraries

 

Microsoft Corporation
October 2003

Applies to:
    Microsoft® .NET Framework
    Microsoft ASP.NET
    Microsoft Visual Studio® .NET
    Microsoft Visual C#® .NET
    Java Server Pages

Summary: Learn how to convert Java tag libraries to ASP.NET Web form controls. (11 printed pages)

Contents

Tag Libraries
Converting Tag Libraries by Using the Java Language Conversion Assistant
ASP.NET Web Form Controls
Summary

In a Web application, a common design goal is to separate the display code from business logic. Java tag libraries are one solution to this problem. Tag libraries allow you to isolate business logic from the display code by creating a Tag class (which performs the business logic) and including an HTML-like tag in your JSP page. When the Web server encounters the tag within your JSP page, the Web server will call methods within the corresponding Java Tag class to produce the required HTML content.

Microsoft® ASP.NET uses Web form controls to serve the same purpose as Java tag libraries. Similar to JSP tags, Web form controls are added to an ASP.NET Web page using an HTML-like syntax. Unlike JSP tags however, a Web form control is actually an object that is contained within your ASP.NET page. This allows you to access information from your Web form control both before and after the page is loaded. The Microsoft® .NET Framework contains many ready-to-use Web form controls, including a Calendar Web form control and a Crystal Reports Viewer Web control. If you require different functionality than is provided by these Web form controls, you can either extend the existing Web form controls or create your own Web form controls by implementing various interfaces.

In this article, we will briefly review tag libraries in Java. We will then discuss how the Java Language Conversion Assistant (JLCA) will convert tag libraries and what you must to do clean up the conversion. Finally, we will provide an overview of Web controls and their use in ASP.NET

Tag Libraries

Tag libraries were designed so that Java code could be executed within a JSP page without using Java script blocks, which clutter up the HTML and break the design goal of separating display code from business logic. Instead of script blocks, tag libraries allow you to create custom HTML-like tags that map to a Java class that performs the business logic. Groups of these HTML-like tags are called tag libraries. Creating and using a custom tag library involves three things:

  • One or more classes that implement the javax.servlet.jsp.tagext.Tag interface. The Tag interface defines six methods that allow your JSP page to use the class to create the desired HTML output. There are also classes/interfaces that implement/extend the Tag interface, such as TagSupport and BodyTagSupport, to make it easier for you to develop your custom tag.
  • An XML document that describes your tag library. Tag library description files must conform to the JSP tag library description DTD, and generally have an extension of "tld".
  • Importing the tag library to the JSP page using the taglib directive.

Once the three requirements are met, you can use the tags in your tag library anywhere within your JSP page.

Tag Libraries in www.codenotes.com

On the CodeNotes site, we made use of the tag libraries included in the Struts framework, and did not use any tag libraries that were developed in house. Because we did not include the Struts source code with our conversion, the tag libraries did not convert at all. However, for the purposes of demonstrating a sample tag library conversion, we will use a tag that fills a <select> tag with books stored in a database. At the end, we will be able to populate our <select> element using code similar to the code in Listing 1.

Listing 1. Books.jsp

<%@ taglib uri="/WEB-INF/BookTags.tld" prefix="book" %>
<!-- contents removed for clarity -->
<select name="bookID">
   <book:BookList/>
</select>
<!-- rest of jsp page removed for clarity -->

When a user browses to our Books.jsp page, they will see listing of all the books, for which the HTML will look like Listing 2.

Listing 2. The HTML for our listing

<select name="bookID">
   <option value='BU1032'>The Busy Executive's Database Guide</option>
   <option value='PS7777'>Emotional Security: A New Algorithm</option>
   <option value='PS1372'>Computer Phobic AND Non-Phobic Individuals:
     Behavior Variations</option>
   <!-- the rest of the options were removed for brevity -->
</select>

As we can see from Listing 2, the main requirement of our Tag class is to produce a String containing multiple<option>elements. The BookListTag in Listing 3 is an example of a Tag class that performs this task. As you can see, BookListTag extends the TagSupport class. The TagSupport class is an implementation of the Tag interface that allows you to create a custom tag by overriding only a few methods instead of implementing the entire Tag interface. You will notice that all of our code takes place within the doStartTag() method. As its name implies, doStartTag() is called whenever the corresponding start tag appears in the JSP page. By using the JSP page's printwriter object within this method, all the strings that we write will replace the occurrence of the start tag in the JSP page.

Listing 3. BookListTag.java

package books;

public class BookListTag extends TagSupport
{
   public int doStartTag()
   {
      try
      {
         JspWriter out = pageContext.getOut();
         Hashtable books; 
         /* populate books from the database */

         String id = new String();
         for (Enumeration e = books.keys();e.hasMoreElements();)
         {
            id = e.nextElement().toString();
            out.println("<option value='" + id + "'>" +
            books.get(id) + "</option>");
         }
      }
      catch (Exception e)
      {
         System.out.println(e);
      }
      return SKIP_BODY;
   }
}

The last step in using our book list tag is to register it in a tag library description file, which is shown Listing 4.

Listing 4. BookTags.tld

<!DOCTYPE taglib PUBLIC
   "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
   "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">
<taglib>
   <tlibversion>1.0</tlibversion>
   <jspversion>1.1</jspversion>
   <shortname>BookTags</shortname>
   <info>Tags for Book Application</info>

   <tag>
      <name>BookList</name>
      <tagclass>books.BookListTag</tagclass>
      <info>Outputs product list for a form</info>
   </tag>

</taglib>

Recall from Listing 1 that the first line in our JSP page was a taglib directive that mapped the tag library saved in BookTags.tld to the prefix book. This directive allows us to use any of the tags contained in Listing 4 using the syntax <book: tagName>. When producing an HTML file from the JSP page, the Web server will examine the OrderTags.tld file to find a<tag>element with a<name>element equal to tagName. Once a match has been found, an instance of the class named in the<tagclass>element is created and used to produce the output for the custom tag. For example, when the Web server processes the<book:BookList>tag in Listing 1, it examines the BookTags.tld file to find the BookList<name>element. Once the proper<name>element has been found, the Web server can determine from the<tagclass>element that a BookListTag object should be created. Since<book:BookList/>is a start tag (as well as an end tag), the Web server will then call the BookListTag.doStartTag() method, which produces the desired output.

Converting Tag Libraries by Using the Java Language Conversion Assistant

Provided that you have source code for your tag libraries, the JLCA will cleanly convert the tag functionality in your project. Although the presentation says that nested tags may be a problem, that information was based on an early build. The newest version converts nested tags cleanly. You will still most likely have to clean up whatever code is called within your doStartTag() method (or whatever Tag methods you implement), but the JLCA will ensure that the functionality within your tag will be invoked at the proper time. For example, the JLCA will ensure that wherever the<ord:BookList>tag originally appeared in your JSP page, the functionality contained within the BookListTag.doStartTag() method will be called at the same point in the JLCA-produced ASP.NET page. If you do not have the source code for your tag libraries, you will have to develop your own Web form control, which is discussed in the ASP.NET Web Form Controls section.

In this section, we will walk through the conversion of the tag library from the Tag Libraries in www.codenotes.com section to demonstrate how the JLCA converts a sample tag library. The first thing you will notice after the conversion is that the JLCA created a directive (Listing 5) in the Books.aspx page similar to the one in the Books.jsp page from Listing 1.

Listing 5. The ASP.NET directive for registering the books tag library

<%@ Register TagPrefix="book_1" Namespace= "books"
   Assembly="BookApplication"%>

The ASP.NET Register directive contains similar information to the JSP taglib directive. The Register directive in Listing 5 declares that any tag with the book_1: prefix maps to a control in the books namespace and is found in the BookApplication assembly. In our example in Listing 6, the<book_1:BookListTag>element maps to the books.BookListTag class.

Listing 6. The ASP.NET syntax for calling a server control

<select name="bookID"><book_1:BookListTag id="BookListTag1"
   runat="server"/>

You will notice that there are more attributes for the tag in Listing 6 than in the JSP-equivalent in Listing 1. The id attribute references the variable name of the control in the Books.aspx codebehind. In the conversion of your tag libraries, you will not likely need to do anything in your codebehind, but as explained in the upcoming ASP.NET Web Form Controls section, having access to the control in the codebehind allows you to interact with the control. The runat attribute must be set to "server" and indicates that the<book_1:BookListTag>element is a server control.

One important thing to notice about the conversion of the Books.jsp page is that the JLCA correctly maps the tag in the ASP.NET page to the corresponding Web form control class. During the conversion, the JLCA examines the tag library description files to determine which classes are being invoked by which tags in the JSP pages, and then ensures the resultant ASP.NET pages call the correct class.

The only other part of the converted project that reflects the tag library is the BookListTag.cs file (Listing 7, which was created from the BookListTag.java file).

Listing 7. BookListTag.cs

using System;
namespace orders
{
   public class BookListTag:WCIterationImpl
   {
      public override int doStart()
      {
         try
         {
            System.Web.HttpResponse out_Renamed = GetOut();
            System.Collections.Hashtable books;
            /* populate books from the database */

            // UPGRADE_TODO removed for clarity
            for (System.Collections.IEnumerator
            e = h.Keys.GetEnumerator(); e.MoveNext(); )
            {
               // UPGRADE_TODOs removed for clarity
               id = e.Current.ToString();
               // UPGRADE_TODO removed for clarity
               out_Renamed.Write("<option value='" + id + "'>" +
               books[id] + "</option>" + "\r\n");
            }
         }
         catch (System.Exception e)
         {
            // UPGRADE_TODO removed for clarity
            System.Console.Out.WriteLine(e);
         }
         return SkipBody;
      }
   }
}

There are two things you should notice about the BookListTag class:

  • Instead of the functionality being placed in a doStartTag() method, the functionality is placed within the doStart() method. This is simply a change in name and there is no difference in functionality associated with this change.
  • The BookListTag class extends the WCIterationImpl class. WCIterationImpl is a JLCA-created class found in the SupportClass.cs file. WCIterationImpl contains methods that allow an implementation of the UserControl class (the base class for most server controls) to have methods similar to those contained in the Java Tag interface. The JLCA takes care of mapping from the Tag methods to WCIterationImpl methods, so you do not have to do anything with the WCIterationImpl class.

The JLCA did flag a few issues during the conversion of BookListTag.java to BookListTag.cs. Specifically, the JLCA mentioned that there might be some problems due to the conversion from java.util.Enumeration to System.Collections.Ienumerator, as well as some problems stemming from changing the Java toString() method to the C# ToString() method. While in some instances, these issues may cause problems, they do not affect the functionality of the BookListTag class so they can be ignored. This means that without making any changes to the converted code, our JSP tag was converted successfully into an ASP.NET Web control.

ASP.NET Web Form Controls

You may find that the terminology used to describe Web form controls and other controls can get confusing because they all have similar sounding names. The following is a brief discussion of terms that you are likely to hear when discussing Web form controls:

  • Server controls are objects that are instantiated and run on the Web server and produce HTML and/or JavaScript that will be embedded in the final HTML page. Server controls can be divided into two more specific categories: Web controls and Mobile controls.
  • Web controls are used in pages that are designed to be viewed in a Web browser. Web controls can be divided into two more specific categories: HTML controls and Web form controls.
  • Mobile controls are used to produce content intended to be displayed on a mobile device. Mobile controls are located in the System.Web.UI.MobileControls namespace.
  • HTML controls are Web controls that have a direct map to an HTML element. By using an HTML control instead of an HTML element, you can manipulate the contents of the element within the codebehind of the ASP.NET page allowing the display to be dynamic. HTML controls are located in the System.Web.UI.HtmlControls namespace.
  • Web form controls are Web controls that provide functionality for which there is not necessarily a corresponding HTML element. For example, there is a Button Web form control, which has a corresponding HTML element (an input button) and there is a Calendar Web form control for which there is no corresponding HTML element. The difference between using a Web form control for an HTML element and using the corresponding HTML control is that the HTML control is limited by the attributes/functionality of the HTML element while the Web form control may incorporate more or different HTML elements depending on the target browser to achieve your desired look-and-feel. However, because a Web form control does not map directly to an HTML element, there is no guarantee that your Web form control will appear the same on all browsers. For example, the TextBox Web form control can span multiple lines when viewed in Internet Explorer. However, on some versions of Netscape, the TextBox will only be a single line, similar to the HTML TextField element. Web form controls are located in the System.Web.UI.WebControls namespace.

In this article, we will focus our discussion on the Web form controls because those are the server controls that most closely match the functionality of tag libraries.

Built-in Web Form Controls

ASP.NET includes a variety of built-in Web form controls that can be used to add graphical elements to your Web pages. They include labels, calendars, buttons, images, tables, and many others. All Web form controls can be added to your ASP.NET page by dragging the associated icon from the Web Forms tab of the Toolbox to the desired location on your Web form. Once a Web form control is added to your page, it can be configured through the Properties tab. As we alluded to in Converting Tag Libraries by Using the Java Language Conversion Assistant, once a Web form control is added to your Web form, an associated object is added to the codebehind class. This means that anywhere within the codebehind, you can have access to the properties of all the Web form controls in the associated page. For example, in the button_click event for a Button Web form control, you can access the text the user entered in a TextBox. This level of interactivity truly allows you to separate the user interface from the business logic, as you can verify that forms have been entered correctly (that a valid value has been entered for each field) before performing the necessary business logic. It also provides a convenient and logical location for all classes for a specific user interface (the .aspx page and the associated codebehind) instead of the Java method of using a JSP page and an associated servlet which has no direct link to the JSP page.

For an example of how easy it is to use Web form controls, we will create a simple application containing a text box and a button. When the user clicks the button, the String in the textbox is converted to upper case.

First, we drag a TextBox and a Button from the Web Forms tab on the Toolbox to the ASP.NET page.

Once you have added both controls to the ASP.NET page, double-click the button control to create the Button1_Click() method and configure the ASP.NET page to activate this method whenever the button control is clicked. By adding the single line of code in Listing 8 to the Button1_Click() method, our application will now convert the user-entered String to upper case.

Listing 8. Converting the value in a TextBox to uppercase

private void Button1_Click(object sender, System.EventArgs e)
{
   TextBox1.Text = TextBox1.Text.ToUpper();
}

While Listing 8 contains very little functionality (it simply manipulates the TextBox.Text property which is a String representing the current value of the TextBox), the ASP.NET Web server is actually doing a lot of work behind the scene. When converting the ASP.NET page into an HTML page for viewing, the Button Web form control is converted into an HTML input submit element. When the user clicks the button, the form is submitted from the client's browser to the Web server. When the Web server receives the posted form, it populates the objects in the codebehind to reflect the user-entered values, and then calls the Button1_Click() method to handle the button click. After the Button1_Click() method has been executed, the Web server uses the new values of all the objects in the codebehind to build the HTML file that will be sent back to the user.

While our example only used the Button and TextBox Web form controls, all Web form controls are handled by the ASP.NET Web server in a similar manner. Please consult the MSDN® Library for more information on specific Web form controls.

Data-Bound Controls

A special subset of the built-in Web form controls is the two data-bound controls, DataGrid and DataList. These two classes allow you to display and format data from a database, or from any other valid data source using the ADO.NET classes. A valid data source is any object that implements the IEnumerable interface. Data-bound controls are used in a manner similar to the built-in Web form controls. In the "Data Bindings" article, we provide an in-depth discussion of data-bound controls.

Custom Web Controls

If the Web form controls included with the .NET Framework do not provide your desired functionality, there are three different ways you can create your own Web control:

  • Create your own Web control by extending the System.Web.UI.WebControls.WebControl class. The WebControl class includes a variety of properties describing the display characteristics of the Web form control, such as BackColor (for background color), ForeColor (for foreground color), Width and Height. The WebControl.Render() method is called to produce the HTML content for your Web control and is the method that you will override in almost all custom Web controls.
  • Extend an existing Web form control and override one of its methods to include your own functionality. All existing Web form controls extend the WebControl class and will use the Render() method to produce their HTML output. Depending on your desired functionality, you may end up overriding the Render() method or changing the functionality of the property methods, or some combination of the two.
  • Create a Web forms user control. A Web forms user control can be thought of as an ASP.NET page with some restrictions. Like a normal ASP.NET page, a Web forms user control is created using the IDE, and the same controls can be added to the Web forms user control. However, because a Web forms user control is intended to be a component in an ASP.NET page and not an entire ASP.NET page, certain HTML elements, such as <HTML> and <HEAD> should not be included in the Web forms user control. A Web forms user control can be compiled and added to an ASP.NET page if it contains any of the restricted HTML elements, but the compiler will generate warning messages warning you that these elements should not be used. Also, if you include some of the restricted elements, your Web forms user control may have an unpredictable effect on the parent ASP.NET page. For example, if both your ASP.NET page and a Web forms user control contain an <HTML> element, you cannot be sure how the user's browser will display the page.

Regardless of which way you wish to create your own Web form control, there are several concepts that you will need to be aware of. In this article, we will discuss these concepts and direct you to places with a more in-depth examination of creating your own Web form controls.

You can find more about creating custom controls in the MSDN Magazine article Develop Polished Web Form Controls the Easy Way with the .NET Framework.

Control templates

Control templates allow developers to override certain aspects of a control's visual appearance. Essentially, they specify how the control's element will be rendered at run time. For example, you can customize the appearance of a DataGrid by providing a template that describes how each individual row, alternating row, or selected row will be rendered. Other iterative controls, such as DataList and Repeater also make use of control templates.

Rendering

When writing a custom Web form control, you must make special provisions with respect to how the control renders within the Microsoft Visual Studio® design environment. There are two things you must concern yourself with:

  • How the control renders on the client; that is, its client-side representation
  • How the control renders within the design environment

The latter is achieved by associating the control with a Designer class by using the Designer attribute. When the control is dragged onto a Web form, Visual Studio .NET instantiates the Designer class to oversee the design-time rendering of the control. The Designer class performs additional functions such as prescribing how a control's properties are modified within the environment, and how such properties affect the client-side rendering of the control. Information on Designer classes can be found in the MSDN Library.

ViewState

The purpose of the ViewState field is to make the properties of a Web control accessible when a user posts a page back to the server. For example, when a user enters information into a page (such as a name, a credit card number, or an e-mail address) a hidden ViewState field stores those values in a single encoded string. This field allows information to be posted back to the server without loss of client-side information.

See also

  • Building ASP.NET Custom Controls describes ASP.NET custom Web controls, provides an example of creating a custom Web control, and illustrates how you can register this custom control with Visual Studio .NET.
  • Web User Controls and Web Custom Controls provides an overview and examples of Web user controls and custom Web controls.
  • Building a Custom Web Control describes creating a custom Web control that inherits from the TextBox Web form control, and automatically adds a required field validator at run time. Thus, this custom Web control eliminates the need to use the required field validator in your ASP.NET pages.
  • Creating Web Server Control Templates Programmatically illustrates increasingly sophisticated ways to create templates for Repeater, DataList, and DataGrid controls, providing examples in both Microsoft Visual Basic® .NET and Microsoft Visual C#® .NET.

Summary

Custom tag libraries and Web controls serve a similar function, and the JLCA will automatically convert your tag libraries into Web controls. However, if you do not have the source code for your custom tag libraries, you will have to either replace the code with existing ASP.NET Web controls, or write your own custom Web controls. In either case, ASP.NET offers a wide variety of options for replacing tag libraries.

© Microsoft Corporation. All rights reserved.