5,154,487 members and growing! (19,794 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General     Intermediate License: The Code Project Open License (CPOL)

Manage ASP.Net Web Server Controls, Event Handler and Server Side Validation using XML and XSLT

By Ehsanul Haque

An article on Managing ASP.Net Web Server Controls, Event Handler and Server Side Validation using XML and XSLT
C# (C# 1.0, C# 2.0, C# 3.0, C#), .NET (.NET, .NET 2.0), ASP.NET, Dev

Posted: 18 Apr 2008
Updated: 18 Apr 2008
Views: 3,093
Announcements



Search    
Advanced Search
Sitemap
10 votes for this Article.
Popularity: 4.55 Rating: 4.55 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
2 votes, 20.0%
3
1 vote, 10.0%
4
7 votes, 70.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

In most cases server controls are very useful in ASP.Net web application since they have some valuable events (for example: click event, data binding event, data bound event, etc) and many advance functionality like state management, input validation, etc. In general XSLT produce plain xml or html without any hassle but if we want to create our asp.net server control by using XML and XSLT then we should follow some procedure which will be described below

XML has a vast use in web application and when we combine XML and XSLT, it shows its own strength and beauty which can speed up our application very much. One major benefit of using XML is column flexibility. Suppose, there are two types of addresses in our application 1. home address and 2. office address. It can be increase or decrease anytime without changing much code. And using XSLT we will create not only server controls but also define their events which will work like a magic.

Requirements

I am assuming that the reader of this article have basic knowledge in XML, XSLT and ASP.Net.

Using the code

We will follow the following steps to get the things done:

  • Prepare XML document
  • XSLT document to transform XML data
  • C# code to instantiate the controls and event handler

Consider the following XML

<root>
<Employee Id="1">
      <Address Caption="Address">
        <Home Caption="Home 1">
          <Street Caption="Street 1" Type="Text">Road#  27, House# 13, Banani</Street>
          <Street Caption="Street 2" Type="Text">
           </Street>
          <City Caption="City" Type="Text" Required="yes">Dhaka</City>
          <Zip Caption="Zip" Type="Text">1213</Zip>
          <Country Caption="Country" Type="CountryDDL">BD</Country>
        </Home>
        <Home Caption="Home 2">
          <Street Caption="Street 1" Type="Text">Sector-  10</Street>
          <Street Caption="Street 2" Type="Text">Uttara</Street>
          <Street Caption="Street 3" Type="Text">
           </Street>
          <City Caption="City" Type="Text" Required="yes">Dhaka</City>
          <Zip Caption="Zip" Type="Text">1230</Zip>
          <Country Caption="Country" Type="CountryDDL">BD</Country>
        </Home>
      </Address>
    </Employee>
    <Employee Id="2">
      <Address Caption="Address">
        <Home Caption="Home 1">
          <Street Caption="Street 1" Type="Text">J-13,  Road 27</Street>
          <Street Caption="Street 2" Type="Text">Banani</Street>
          <City Caption="City" Type="Text">Dhaka</City>
          <Zip Caption="Zip" Type="Text">1213</Zip>
          <Country Caption="Country" Type="CountryDDL">BD</Country>
        </Home>
        <Home Caption="Home 2">
          <Street Caption="Street 1" Type="Text">Michigan Avenue</Street>
          <Street Caption="Street 2" Type="Text">Suite 2800</Street>
          <Street Caption="Street 3" Type="Text">
           </Street>
          <City Caption="City" Type="Text">Chicago</City>
          <Zip Caption="Zip" Type="Text">60601</Zip>
          <Country Caption="Country" Type="CountryDDL">USA</Country>
        </Home>
      </Address>
    </Employee>
  </root>
  

We have to show the addresses like below:

Article

Since there are multiple employee’s data in our XML document, we have to select the requested employee’s data among them. For this purpose, we have to create argument list and need to pass the employee id through xslt parameter.

    
//create argument list
  XsltArgumentList xslArg = new XsltArgumentList();
  xslArg.AddParam("employeeId",  "", ddlEmployee.SelectedValue);

//load the data
  XPathDocument xdoc = new XPathDocument(Server.MapPath("Address.xml"));
  //load Xslt
  XslCompiledTransform transform  = new XslCompiledTransform();
  transform.Load(Server.MapPath("DynamicControls.xslt"));
  StringWriter sw = new  StringWriter();

  //transform it
  transform.Transform(xdoc, xslArg,  sw); 
  

And we will receive the argument from xslt like below

    
<!--<xsl:param  name="employeeId"/>-->
  <xsl:param name="employeeId"/>

If we see our XML then we will find that there are a ‘Caption’ attribute in each node. This is the caption of each value while show the output. On the other hand, to give input some time it is better to show a dropdown list rather than a traditional textbox. Suppose, when user will choose country it is more meaningful to show a country list rather than a textbox. To fulfill this purpose, we have a similar attribute named ‘type’ in some xml node. And by inspecting this attribute we have to render the appropriate aspnet server control from XSLT

    
<xsl:choose>
     <xsl:when test="translate($varType,$up,$lo)='countryddl'">
        <asp:DropDownList  id="{concat('ddlCountry',$rowindex)}" runat="server" 
        DataTextField="Text" DataValueField="Value">
              <asp:ListItem  value="{.}">
                    <xsl:value-of  select="."/>
               </asp:ListItem>
        </asp:DropDownList>
     </xsl:when>
     <xsl:otherwise>
        <asp:TextBox ID="{$varId}" runat="server" Text="{.}" width="205px" ></asp:TextBox>
        <xsl:if test="translate($isRequired,$up,$lo)='yes'">
              <asp:RequiredFieldValidator  ErrorMessage="  Required Field" runat="server" 
        ControlToValidate="{$varId}" />
        </xsl:if>
     </xsl:otherwise>
  </xsl:choose>
  

At last, we must have to declare a button to save the inputted data in xslt

    
<asp:Button  ID="btnSaveAddress" runat="server" BackColor="White"
                BorderColor="DeepSkyBlue" BorderStyle="Solid" BorderWidth="1px" 
        Font-Names="Tahoma" Font-Size="10pt" Text="Save Data" />

Now we have to set event handler for this button from the code behind. ParseControl function will make our work very easy by parsing the XML string to asp.net server control. To get a reference of newly created controls we have to call the FindControl method. As soon as we get the reference of the control we can set event handler for that control. One thing is very important to know that the event handler adding process should be after parsing the control. Because before parsing, the control will not be available. Also Parsing should be in Page_Init event so that the controls will be found in the rest of the life cycle.

    
//parse control
  Control ctrl = Page.ParseControl(result);
  phEmployeeAddress.Controls.Add(ctrl);

//find control to add event handler
 Button btnSaveAddress = (Button)phEmployeeAddress.FindControl("btnSaveAddress");
  btnSaveAddress.Click += new EventHandler(btnSaveAddress_Click);
 

We have almost covered everything. The most interesting thing is, using XSLT our ASPX page will become very simple and clear look. Here is the full aspx source

    
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" 
Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head runat="server">
      <title>Dynamic ASP.net Controls Using Xslt</title>
  </head>
  <body>
      <form id="form1" runat="server">
      <div style="float: right; background-color: Yellow">
          <asp:Label ID="lblMessage"  runat="server"  Text="Label"></asp:Label>
      </div>
      <div>
          <asp:Label ID="Label1" runat="server"  Text="Choose  Employee"></asp:Label>
          <asp:DropDownList ID="ddlEmployee"  runat="server"  Width="128px">
              <asp:ListItem Value="1">Ehsan</asp:ListItem>
              <asp:ListItem Value="2">Ashraf</asp:ListItem>
          </asp:DropDownList>
           <asp:Button ID="btnLoadData" runat="server" BackColor="White" 
        BorderColor="DeepSkyBlue" BorderStyle="Solid"  BorderWidth="1px"  
        Font-Names="Tahoma"  Font-Size="10pt"  Text="Load  Data"
              OnClick="btnLoadData_Click"  /><br />
          <br />
          <asp:PlaceHolder ID="phEmployeeAddress"  runat="server"></asp:PlaceHolder>
      </div>
      </form>
  </body>
  </html>
  

All the XSLT controls will be extracted to PlaceHolder and here is the entire XSLT used to render the html and server controls

    
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:asp="remove">
    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
    <!--<xsl:param name="employeeId"/>-->
    <xsl:param name="employeeId"/>
    <xsl:template match="/root">
      <xsl:for-each select="Employee">
        <xsl:if test="@Id = $employeeId">
        <table width="100%" border="0" cellspacing="0" cellpadding="0"  bgcolor="#FFFFFF">
          <tbody>
             <tr>
               <td>
                 <xsl:apply-templates  select="Address">
                  <!--<xsl:with-param name="count" select="$count"/>-->
                 </xsl:apply-templates>
               </td>
             </tr>
             <tr>
               <td>&#160;</td>
             </tr>
             <tr>
               <td align="right">
                 <span style="margin-right:20%">
                   <asp:Button ID="btnSaveAddress" runat="server" BackColor="White"
                     BorderColor="DeepSkyBlue" BorderStyle="Solid" BorderWidth="1px" 
            Font-Names="Tahoma" Font-Size="10pt" Text="Save Data" />
                 </span>
                 <span>&#160;</span>
               </td>
             </tr>
           </tbody>
        </table>
        </xsl:if>
      </xsl:for-each>
    </xsl:template>
    <xsl:template name="HomeAddress" match="/root/Employee/Address">
      <table width="100%">
        <tr>
          <td height="30" colspan="2" align="left">
             <strong>
               <xsl:value-of select="@Caption"/>
             </strong>
           </td>
        </tr>
        <tr>
          <td height="2" colspan="2" align="left" bgcolor="#CCCC99"></td>
        </tr>
        <tr>
          <td width="50%" height="30" align="left" valign="top">
             <table width="100%" border="0" cellspacing="0" cellpadding="0">
               <tr>
                 <td colspan="4" height="4"></td>
               </tr>
             <tr>
                 <xsl:for-each select="child::*">
                   <xsl:variable name="rowindex" select="position()"></xsl:variable>
                   <td align="left" valign="top">
                     <table cellpadding="4">
                      <tr>
                        <td colspan="4" height="28" align="left" valign="top">
                          <strong>
                            <xsl:value-of select="@Caption"/>
                          </strong>
                        </td>
                      </tr>
                     <xsl:for-each select="child::*">
                        <xsl:variable name="varType" select="@Type"></xsl:variable>
                        <xsl:variable name="isRequired" select="@Required"></xsl:variable>
                        <xsl:variable name="varId" 
            select="translate(concat(concat(concat(@Caption,'_'),$rowindex),position()),'  ','_')"></xsl:variable>
                        <xsl:variable name="up" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
                        <xsl:variable name="lo" select="'abcdefghijklmnopqrstuvwxyz'"/>
                        <tr>
                          <td height="28" align="left" valign="top">
                            <xsl:value-of select="@Caption"/>
                          </td>
                          <td  colspan="3" align="left" valign="top" height="28">
                            <xsl:choose>
                              <xsl:when test="translate($varType,$up,$lo)='countryddl'">
                                <asp:DropDownList id="{concat('ddlCountry',$rowindex)}" 
                runat="server" DataTextField="Text" DataValueField="Value">
                                  <asp:ListItem value="{.}">
                                   <xsl:value-of select="."/>
                                  </asp:ListItem>
                               </asp:DropDownList>
                              </xsl:when>
                              <xsl:otherwise>
                                <asp:TextBox ID="{$varId}" runat="server" Text="{.}" 
                width="205px" ></asp:TextBox>
                                 <xsl:if test="translate($isRequired,$up,$lo)='yes'">
                                  <asp:RequiredFieldValidator ErrorMessage=" 
                Required Field" runat="server" ControlToValidate="{$varId}" />
                                </xsl:if>
                              </xsl:otherwise>
                            </xsl:choose>
                         </td>
                        </tr>
                       </xsl:for-each>
                     </table>
                   </td>
                 </xsl:for-each>
              </tr>
             </table>
           </td>
        </tr>
      </table>
    </xsl:template>
  </xsl:stylesheet>

Summary

Asp.net server controls are very powerful in web application without any doubt and by combining XML and XSLT with it we can make web application more powerful, easier, efficient and re-usable. Also by using XML and XSLT the application UI script will look clean and will be easier to maintain. I hope this will be great start for those who wants to make their site more dynamic and structured using XML and XSLT with the great power of ASP.Net controls. Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ehsanul Haque


Ehsanul Haque is a Software Engineer, who is dedicated to Microsoft .NET based development. He is involved with several US based software projects from his country. Already he has completed few projects, which are being used by several users of different countries, such as USA, Japan, and Bangladesh. While developing and managing a team, he maintains a set of well defined engineering practices developed by him and other online developer community. Beside software development, he has also written several technical articles.

When not engaged with technical stuffs, he likes to pass time with his friends, and family members, listens music, watching TV, travel or by reading books.
Occupation: Software Developer (Senior)
Company: Desme Inc
Location: Bangladesh Bangladesh

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
  (Refresh) 
Subject  Author Date 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 18 Apr 2008
Editor:
Copyright 2008 by Ehsanul Haque
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project