Click here to Skip to main content
15,881,852 members
Articles / Web Development / ASP.NET
Article

Go Beyond the limitations of ASP.NET Form

Rate me:
Please Sign up or sign in to vote.
4.25/5 (18 votes)
17 Mar 20044 min read 104K   1.5K   39   12
An article on the limitations of ASP.NET Form, especially the missing PostBack Action of a <form> element.

Sample image

Introduction

One of the most common hitches that ASP developers encounter when they first approach ASP.NET is that managed Web applications must be written according to a single-form interface model. In the single form interface model, each page always posts to itself by default using the POST HTTP method. The HTTP method and the target frame of the post can be programmatically adjusted using ad hoc form properties— Method and Target. The final destination of the postback can't be changed in any way. You can correlate the terminologies of a single-form interface to the single-document interface (SDI) and multiple-form interface to the multiple-document interface (MDI) in client server.

Following is the description found on MSDN regarding the limitation.

“The action attribute is always set to the URL of the page itself. The action attribute cannot be changed; therefore, you can only post back to the page itself.” (ref: Goto definition on MSDN).

This article is to illustrate the limitation of the ASP.NET Form control, which doesn’t provide the facility of submitting data to other pages or sites.

Let’s consider a situation where either:

  1. We want to perform a search on google.com with search criteria from an ASP.NET web page.
  2. Or we want to look at current stock quote of a Company listed on NASDAQ or NYSE by submitting information from an ASP.NET web page.

We cannot fulfill the above requisites in currently available UI related controls in ASP.NET.

This article is concentrating on the aspects of providing the Action property to a server-side form object based on the very own HtmlForm class itself which further can be extended to adopt multiple-form interface.

For live demo of this submission, navigate to Live Demo site.

Background (HtmlForm class: reviewed)

In HTML and ASP programming, the form element (i.e., <FORM>) features the Action property that programmers use to redirect to another URL after clicking. In ASP.NET, server-side forms are rendered using a class named HtmlForm under the System.Web.UI.HtmlControls namespace. This class doesn't provide the familiar Action property, nor does it supply an alternative property to perform the similar functionality. As a result, the single form interface model is so deep-rooted in ASP.NET that there's no way around it.

Before going into further detail, let's take a little review on HtmlForm. The HtmlForm class is derived from HtmlContainer class and implements the IAttributeAccessor interface. So, the base class (HtmlContainer) provides HtmlForm the ability to govern and contain child controls; IAttributeAccessor interface provides the ability to read and write the attributes of the opening tag (i.e., <FORM …..) itself. The HtmlForm class is not sealed and thus it is permissible for further inheritance as well as customization.

CHtmlForm: a more powerful shape of HtmlForm for ASP.NET

While we reviewed HtmlForm class, we found a starting point to think for providing Action property to it, because the HtmlForm class is not sealed and thus can be further inherited. As like other .NET controls, it also features a bunch of protected, overridable methods that you could exploit to customize the overall behavior. You can achieve this with the help of reflection. As we know, Reflection allows you to access any property on an object, even though the property is marked protected, internal, or private.

Let us start the process of customization of HtmlForm; CHtmlForm is an inherited class from HtmlForm class under the System.Web.UI.HtmlControls namespace. HtmlForm class provides 4 protected as well as public methods; one of them is the RenderAttributes method. The purpose of this method is to provide user defined implementation of the default rendering process. It has a parameter of the type HtmlTextWriter, to render final values of all attributes like Method, target, name, id, action to the parent object; for our case, it is the Page object.

The HtmlTextWriter object formulated a new Action attribute by resolving the hidden GetActionAttribute of HtmlForm object.

C#
    /// <summary>
    /// purpose: Overridden to render custom Action attribute
    /// The main purpose of the Overridding is to grab the
    /// "action" attribute of the original 
    /// form
    /// </summary>
    protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer) {

            
        // Prepare our own action , method and name
        writer.WriteAttribute("name", this.Name);
        writer.WriteAttribute("method", this.Method);
        writer.WriteAttribute("action", this.ResolveUrl(this.Action), true);
        // Remove From HtmlForm, with changes to Action
        this.Attributes.Remove("name");
        this.Attributes.Remove("method");
        this.Attributes.Remove("action");
    
        string submitEvent = this.Page_ClientOnSubmitEvent;
        // Now check the onsubmit event associated with Htmlform 
        if (submitEvent != null && submitEvent.Length > 0) {
            // ok.. this for has a "OnSubmit" 
            if (this.Attributes["onsubmit"] != null) {
                submitEvent = submitEvent + this.Attributes["onsubmit"];
                this.Attributes.Remove("onsubmit");
            }
            //Add some new Attributes to make the new form little more rich
            writer.WriteAttribute("language", "javascript");
            writer.WriteAttribute("onsubmit", submitEvent);
        }
        writer.WriteAttribute("id", this.ClientID);

        // following is meant for HtmlContainerControl
        this.ViewState.Remove("innerhtml");
        // following is meant for HtmlControl
        this.Attributes.Render(writer);
    }
//   The above code shows the overriden method RenderAttribute(writer)
C#
private Object GetHideProperty(Object target, 
          Type targetType, String propertyName ) 
{
    PropertyInfo property = targetType.GetProperty(propertyName, 
                            BindingFlags.IgnoreCase |
                            BindingFlags.Instance | BindingFlags.NonPublic );
    if ( property != null ) {return property.GetValue(target, null);}
    else {return null; }
}
    
/// The above code shows the GetHideProperty which uses reflection
/// to access any property on an object, even though the property
/// is marked protected, internal, or private.

Points of Interest

Following code snippet shows how the final structure of a page will look like:

ASP.NET
<%@ Register TagPrefix="dtform" Namespace="DerivedTool.WebControls" 
                  Assembly="DerivedTool.WebControls.HtmlForm" %>
        
  <dtform:CHtmlForm Action="some_other_page.aspx" runat="server"> 
        <asp:TextBox id="symbols" runat="server" value=></asp:TextBox> 
        <asp:Button runat="server" Text="check Quote" /> 
  </dtform:CHtmlForm>

If you want to PostBack to the same ASP.NET page, just leave Action property as blank. For live demo of this submission, navigate to Live Demo site.

How to deploy CHtmlForm

Though deployment of this server–side control is very easy and simple, I am providing following steps to test the control with ASP.NET.

  1. Extract all the files in the zip file to a folder say c:\deriveForm.
  2. Make C:\deriveform as a virtual directory by giving name as “derivedemo”, if you have IIS server installed on your machine, other wise put the folder on a machine having IIS installed in it.
  3. Make a folder named bin under C:\deriveform and copy DerivedTool.WebControls.HtmlForm.dll to this new folder.
  4. Open your browser and navigate to http://localhost/derivedemo/derivedForm.aspx

    Or navigate to http://<SERVER>/derivedemo/derivedForm.aspx (if you don’t have IIS on the current machine).

Enjoy!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Currently working as a Sr. Software Architect .
I was former employee of companies like Wipro Technologies, Infogain corporation, futuresoft. I worked as Architect in Microsoft Business Unit of Wipro Technologies. Worked as Lead Project Analyst for Business Engine network , a backoffice tool
. I've been involved in providing software solutions for last 7 years, in ERP,SCM,workflow,Reporting tool etc. to customers. Now, I'm designing applications in .NET and also exploring its features for 1 and half years.
Reach me at My ID

Comments and Discussions

 
GeneralSubmit form when action set to server address Pin
Ajay Kale New18-Oct-10 22:13
Ajay Kale New18-Oct-10 22:13 
GeneralOther simple way without overriding Pin
Yunus Kurniawan8-Jul-08 4:29
Yunus Kurniawan8-Jul-08 4:29 
GeneralAnother simpler way Pin
Jeff X. Chang23-Mar-05 21:01
Jeff X. Chang23-Mar-05 21:01 
Generalhmmm....strangely familiar Pin
an_phu3-Mar-05 11:08
an_phu3-Mar-05 11:08 
GeneralViewstate Pin
vanalan20-Jan-05 11:17
vanalan20-Jan-05 11:17 
QuestionHow to get the posted data in the posted the ASP.NET page? Pin
millavenue30-Nov-04 10:47
millavenue30-Nov-04 10:47 
GeneralExcatly What I Needed Pin
eraserhead5-Oct-04 6:43
eraserhead5-Oct-04 6:43 
GeneralVB.net Class Pin
M@dHatter8-Jun-04 22:23
M@dHatter8-Jun-04 22:23 
GeneralSweet! Pin
Bayonet-Recon19-Mar-04 7:02
Bayonet-Recon19-Mar-04 7:02 
QuestionGood article....when do you plan to add the multiple form capability? Pin
Anonymous18-Mar-04 7:14
Anonymous18-Mar-04 7:14 
AnswerRe: Good article....when do you plan to add the multiple form capability? Pin
Joyprakash Saikia18-Mar-04 16:55
Joyprakash Saikia18-Mar-04 16:55 
GeneralMultiple Server Forms Too Pin
Paul Wilson18-Mar-04 7:05
Paul Wilson18-Mar-04 7:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.