Click here to Skip to main content
Click here to Skip to main content

Managing State with HTML Forms in ASP.NET - A Lightweight Alternative

, 12 Dec 2008
Rate this:
Please Sign up or sign in to vote.
A flexible, lightweight library for form processing without using viewstate, postbacks, or server-side form elements.

Introduction

To achieve the full benefits of ASP.NET (as opposed to ASP or PHP), one generally uses the traditional Server Control - ViewState - PostBack model to speed development time by automatically handling maintaining the state of the application between form submissions and allowing the developer to focus on functionality instead of wasting his time doing things such as repopulating form fields after a postback and writing messy inline code to do it.

However, this model has disadvantages when developing interface heavy applications using complex CSS and JavaScript, and becomes especially problematic when trying to use AJAX that is not part of ASP.NET AJAX - the problem stems from the fact that when using Server Controls (or even HTML controls set to runat=server), the front-end code written by the developer often bears little resemblance to what is generated at the server.  It also can be quite slow, especially when ASP.NET AJAX is introduced.

The library here presents an alternative, allowing the front end to be developed using straight HTML and / or JavaScript, using client side forms, while preserving the ability to maintain page state and to manipulate page content from server-side code without using a single inline tag.  Furthermore, the problem of limited support for "Cross-Page PostBacks" has been solved - the target page that the user is sent to after form processing need not have anything to do with the submitting page.

Currently, the library, unmodified, has the following features and will work right out of the box:

  • Maintains the state of INPUT (text, password, radio, checkbox, and hidden) and SELECT  tags between POSTs and / or allows their state to be set from server-side code.
  • Allows ordinary client side container elements (e.g. DIVs, SPANs) to be used as labels and/or panels, and to have their contents set on the server side. 
  • Allows the developer to specify arbitrary JavaScript to run on the target page after form processing is complete.

Using the Library

The library consists of a user control, FakePostBack.ascx, to be placed in the ASPX pages for which you wish to use the library, and the FormProcessor.cs class, to be placed in your app_code folder.

I've bundled a sample "calculator" app to demonstrate usage... Let us go through the example.

The Front-End Code (Demo.aspx)

<%@ Register Src = "FakePostBack.ascx" TagName="FormHelper" TagPrefix="sam" %>
<html>
<head>
</head>
<body onload="FormHelper.Populate();">
<sam:FormHelper runat="server" id="customForm"></sam:FormHelper>
    <form name="calculate" method="post" action="Calculator.aspx">
        <h2>Demo App using Form Processor.NET</h2>
        <b>Enter an integer:</b><br />
        <input type="text" id="num1" name="num1" /><br /><br />
        <b>Enter another integer:</b><br />
        <input type="text" id="num2" name="num2" /><br />
        <input type="submit" value="Calculate Sum" />
    </form>
    
    <div id="sum"></div>
    
    <script>
    function SayHello()
    {
        alert("Thanks for using the calculator.");
    }
    </script>
</body>
</html>	

This is an absolutely standard HTML page. All that has been done to include the front-end portion of the library is to add the FakePostBack.ascx control, and drop it in right about the form in question. The control requires no attributes rather than runat=server. Also, the <body> tag has been modified to run FormHelper.Populate on load - this initializes the control.

The code-behind for the above Demo.aspx page is empty - it is not needed.

The Form-Processing Code (Calculator.aspx.cs)

This is a purely server-side page (Calculator.aspx is blank) and its job is to process the submitted form from Demo.aspx using our FormProcessor class.

Let's look at what happens here:

FormProcessor p = new FormProcessor("Demo.aspx");

//Retrieve the posted fields and do all necessary processing
int a = Int32.Parse(p.Get("num1", "text"));
int b = Int32.Parse(p.Get("num2", "text"));
int c = a+b;

//Specify the text to display on return, and the container to hold it
p.SetLabel("sum", "The sum is: "+c.ToString());

//Add JavaScript, just for fun
p.AddScript("SayHello();");

p.Finish();

An instance of FormProcessor is created, specifying the page to load after processing has been completed - in this case, it is the submitting page - but it can be any page containing the client-side control. 

Just a brief look at some relevant lines that will show you how to use the library:

p.Get("num1", "text") 

This returns the contents of the "num1" input field - it is equivalent to using Request.Form["num1"] but while maintaining state. The second argument of the Get method specifies the type of form field (available values are "text", "select", "radio", "checkbox") - "text" covers hidden and password fields as well.

p.SetLabel("sum", "The sum is: "+c.ToString());

This instructs the client-side module to populate the empty <div id="sum"> with the content specified.

p.AddScript("SayHello();"); 

The JavaScript specified here will be executed on the target page.

p.Finish() 

The browser is redirected to Demo.aspx, the URL specified in the FormProcessor constructor.

Page Before Submission

before.JPG

Page After Submission

after.JPG

How It Works

I won't go too much into detail here - the code in FormProcessor.cs, FakePostBack.ascx, and FacePostBack.ascx.cs are easily understandable, but briefly:

The FormProcessor.cs Get(), SetLabel() and AddScript() methods add to a JSON array. FormProcessor.Finish() places this array into a Session variable, and redirects to the page containing FakePostBack.ascx.

The code-behind for FakePostBack.ascx checks for the presence of the Session variable; if found, it is placed in a public string and then set destroyed.

Finally, the call to FormHelper.Populate() calls JavaScript generated by FakePostBack.ascx - it grabs the string containing the JSON from the code-behind, and if the string is not empty, iterates through the array, populating form fields, setting the content of elements, and executing any script blocks.

Acknowledgements

Sanford Liu, the brilliant product manager at Supernova Interactive, gave me the idea of using JSON as a way of keeping track of validation errors after form submission and then displaying them if errors had occurred.

Then, last night, at about 1 AM, after walking a beautiful young woman to the train station, I realized that I could use this concept to build a workable alternative to server-side forms in ASP.NET. And I did. Smile | :)

Enjoy!

History

  • 12th December, 2008: Initial post

License

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

Share

About the Author

Sam Rahimi
Team Leader World Golf Tour
Canada Canada
Sam Rahimi currently leads the web team at World Golf Tour (www.wgt.com) and has an extensive background in ASP.NET, specializing in social networking and casual gaming.
 
Previously, he has worked for Roblox Corporation on their unique children's MMO as well as spending two years as team lead at Supernova.com, helping bring their social networking site into the modern era and doubling traffic along the way.
 
Sam started as a classic ASP engineer as a summer job 6 years ago to make some money to pay for tuition - to finish a degree in political science - and needless to say, never looked back. His experience has lead him to gain additional experience in the mobile space - J2ME, Android app developmentm, and SMS protocols.
 
And sure, the other engineers in SF may have an IPhone - Rahimi sticks with the EVO all the way!

Comments and Discussions

 
GeneralNeat idea but... Pinmembertaskerov16-Dec-08 4:34 
GeneralRe: Neat idea but... PinmemberSam Rahimi16-Dec-08 6:18 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 12 Dec 2008
Article Copyright 2008 by Sam Rahimi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid