![]() |
Web Development »
ASP.NET »
General
Intermediate
Go Beyond the limitations of ASP.NET FormBy Joyprakash SaikiaAn article on the limitations of ASP.NET Form, especially the missing PostBack Action of a <form> element. |
C#.NET 1.0, .NET 1.1, Win2K, WinXP, Win2003, ASP.NET, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

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:
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.
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.
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.
/// <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)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.
Following code snippet shows how the final structure of a page will look like:
<%@ 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.
Though deployment of this server�side control is very easy and simple, I am providing following steps to test the control with ASP.NET.
Or navigate to http://<SERVER>/derivedemo/derivedForm.aspx (if you don�t have IIS on the current machine).
Enjoy!
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 17 Mar 2004 Editor: Smitha Vijayan |
Copyright 2004 by Joyprakash Saikia Everything else Copyright © CodeProject, 1999-2009 Web15 | Advertise on the Code Project |