Google

Tuesday, January 1, 2008

Access Previous Page's Controls Using Cross Page Postback

How to access previous page's controls

Before Asp.Net 2.0 was introduced, accessing the previous page's controls from a given page was a tricky affair. You had to use nice but not so right features like Session, HttpContext, even cookies in some cases, to persist relevant information from one page to another. Session is useful when you have to persist a bunch of data across the user's session, but it is not suitable for passing random values between pages. The primary reason for this being that as your application gets more and more complex, the Session state could become cluttered and confusing because of similarly named session values, and could easily become a maintainence nightmare. After a period of time, you would not remember what Session state variables you used to pass values between which pages.

Asp.Net 2.0 comes with a very handy feature called the PreviousPage property. This is a public property of the Page class, and refers to the PreviousPage instance. Using this property, you can access the previous page's public properties. You can also access the previous page's controls using the FindControll method.

Let us take an example. Suppose we have the following web page, that has a simple textbox and a button. Note that the button's PostBackUrl property is set to another page, meaning that when the button is clicked, the current webform will post back to the PostBackUrl page (If you are not clear with cross page HTTP postbacks, look at this post).

    <%@ 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>Untitled Page</title>
    </head>
    <body>
     <form id="form1" runat="server">
     <div>
      <asp:Button ID="Button1" runat="server" PostBackUrl="~/Default2.aspx" Text="Button" />
      <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></div>
     </form>
    </body>
    </html>
   

What happens here is that Asp.Net looks at the PostBackUrl property of the button and understands that form needs to be submitted to another form. To achieve this, it emits a javascript function called WebForm_DoPostBackWithOptions that makes sure that the form is correctly submitted to another page. To further understand what I am saying, look at the source for your page (right click, view source). Here's what our button looks like in actual HTML :

     <input type="submit" name="Button1" value="Button" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;Button1&quot;, &quot;&quot;, false, &quot;&quot;, &quot;Default2.aspx&quot;, false, false))" id="Button1" />
   

Now to understand fully how Asp.Net posts back to another form, we must first understand the mechanism Asp.Net uses to postback a form. If you carefully look at the above HTML source for the button, you will see that onclick, the button calls a javascript method called [WebForm_DoPostBackWithOptions]. This method comes out of the box with Asp.Net. To view it's contents, we need to find the Javascript file to which the method belongs to. If you glance at the HTML source of the page, you will see that there is a file called WebResource.axd included with your page :

    <script src="/WebSites1/WebResource.axd?d=wKUbMd8wFV3uZ8WZXaQryA2&amp;t=633245101798773778" type="text/javascript"></script>
   

To look at the actual webresource.axd, do this : Internet Explorer --> Tools --> Settings --> View Files. This will open up a folder, where there will be one or many instances of WebResource.axd. This is a standard Javascript file that contains common Asp.Net page related functionality.

You can go through the WebForm_DoPostBackWithOptions method in the file to understand the exact mechanism for postback. Specifically, note how the [action] property of the webform is changed to the other page. Upon form submission, Asp.Net posts the form to the other page, instead of doing a normal page postback to itself. Upon postback, even though the form posts to another page, the original page's page lifecycle executes upto the [OnLoadComplete] event. After that, Asp.Net transfers the page execution to the other page (I assume it does a Server.Transfer), and also sets the IsCrossPagePostback property for the next page. Once on the other page, it continues the normal page lifecycle of the other page, and renders on page.

All this can get a bit confusing, so let's go through the entire thing again :

1. The first page is Page_A. User clicks a button that has the PostBackURL property set to Page_B.

2. Upon the button click, the [WebForm_DoPostBackWithOptions] javascript method is called. This method is part of the WebResource.axd file.

3. This method sets the form's [action] property to the Page_B, and posts the form.

4. Page_A page lifecycle starts executing upto the OnLoadComplete event, after which Asp.Net transfers execution to the Page_B, also setting Page_B's [IsCrossPagePostback] property on the way. Also, Page_B's PreviousPage property is set to the Page instance object of Page_A. (You know that each page is compiled into an object that derives from System.Web.UI.Page, right. That's the Page Instance Object I was referring to.)

5. Page_B page now starts executing it's normal page lifecycle. Since PreviousPage refers to the instance of Page_A, you can access any public property on the page, any web control on the page, infact, you can call public methods on Page_A.

6. Page_B now executes its normal page lifecycle, accessing public properties/methods/controls on Page_A if required, and renders it's HTML.

I would have loved to explain how I figured out all this internal stuff about Cross Page postbacks, but can't for "lack of space" (it's more like "lack of desire to keep on drooling on the same thing" ;) ), but you can take a look at the source code right here I used to figure out what I did. You can put this code into Debug, setting breakpoints at various key methods to understand how it works.

An oh yes, do remember that you can access 1. Public Properties, 2. Page Controls, 3. Static Variables, 4. Call public methods, using the PreviousPage property. So go ahead and play around with this powerful feature, and find interesting ways to use it in your Asp.Net WebApps.

Thursday, December 27, 2007

Passing values using HTTP POST in Asp.Net

By doing HTTP POST to another page

A lot of Asp.Net developers might not be aware of this, but one of the ways of passing values from one page to another is a normal HTTP POST. Before we dive into it, let me ask if you know exactly what this means : "An Asp.Net webform posts back to itself".

Basically, when you click on a button to submit a webform, you are sending that form back to the server. Here, webform means whatever falls between the <form></form> tags on your page. In technologies such as ASP, you can have multiple <form></form> elements on the same web page. When the user posts back the form, the [action] attribute of the form decides to which page the form gets submitted.

For example, suppose you have a form that looks like this :

<form action="PostPage.aspx" id="SimplePageForm" method="Post">
    Please enter text here that you want to see on the next page : 
                <input type="text" name="myText" id="theTxt" />
    <hr />
    <input type="submit" name="btn" id="btnSubmit" />
</form>

We basically want to create a form that posts to some other page. For e.g., our current form has action="PostPage.aspx". This means that when you submit the current page, it shall post back to PostPage.aspx page, and not to itself. The current FORM's elements shall be available on this other ASPX page, and can be accessed using the .net Request object.

Let me dwell a little bit more on this. On the current form, you have a textbox with the [name] property set to "myText". When you post this page, the entire form's data posts back to the server as a name-value collection. Meaning, a name-value collection will be sent back to the server, where one entry has name = "myText", and value = whatever value you entered in the textbox. There will be similar name-value pair entries for other controls on the page. As an aside, note that HTML handles the POSTed values differently for different controls. For e.g., for a textbox, the value is set to whatever text you enter in the textbox, whereas for a dropdown list, it will be set to the value that has been selected at the time of postback.

Bear in mind that the form is posted to a different page, i.e., PostPage.aspx, so the name-value collection is accessible on the PostPage.aspx. Instead of providing you with the raw posted values, Asp.Net wraps this information in the Request object. You can access the posted value using Request.Form["myText"]. Again, as an aside ;), if you are using <input type="file"> on your form, i.e., if you are using a file upload control, the story is slightly different. In this case, you can access the path of the files to be uploaded using Request.Files.

Finally, all we need to do in the PostPage.aspx is to access the posted values using the Request.Form collection. Take a look at the source code below, before we move to the final "prescriptive guidance" for this type of solution.

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class A_2_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    Response.Write("You typed in : " + Request.Form["myText"]);
    }
}

As is evident, we just get the posted value for the control named "myText" using the Request.Form collection, and print it out.

The above solution is not feasible if you are trying to pass values between ASPX pages. The simple reason for this being that Asp.Net does not allow <form></form> elements to post to any other form other than itself. However, you can have multiple HTML forms on your webpage (ones without runat="server"). The advantage of doing this is that it allows you to show one/more forms to the user at the same time. Depending upon the user action, one of the form is posted back. This way, each form can have its own "processing page" to which it posts back on each submit. I'm not saying this is the best practice solution, but just that even simple HTTP POST can be handy at times.

Wednesday, December 5, 2007

How to run serverside code from client side script

In the last article, we saw how to access server side control values on the client side. However, an even more interesting (and lesser known) mechanism in Asp.Net is running server side code in client side script. This can come in very handy in some situations, as we'll see through the following example. Suppose we need to create a graphical representation of some quantity. Let us say we have two variables on the server side, a [barCount] variable, to indicate the value to be shown on the graph, and a maxCount variable, that determines the maximum value that can be shown in the graph. To give you an idea of what I'm talking about, look at the following screenshot: The variables [maxCount] and [barCount] are serverside variables in your C# code behind file. Note that they have to be made public. maxCount is the total number of bars on the graph, while barCount gives the actual value to be represented on the graph. How did we do it ? One way, of course, is to use a repeater control, and modify it to render the required output. We are not particularly in favor of this approach, because a repeater is more conducive to databinding kind of functionality, not the one we are discussing here. Instead, here's the code we used :

<form id="form1" runat="server">
You Entered :
<br />
maxCount = <%=maxCount %>
<br />
barCount = <%=barCount %>
<table width="100%">
<tr>
<%for(int i = 0; i < maxCount; i++ ) %>
               <%{ %>
                  <%  if( i <= barCount )  %>
<%  { %>
<td style="border-right: #000000 1px solid; border-top: #000000 1px solid; border-left: #000000 1px solid;
color: #6600ff; border-bottom: #000000 1px solid; background-color: #0000cc;">
&nbsp;
</td>
<% }%>
<% else%>
<%  { %>
<td style="border-right: #000000 1px solid; border-top: #000000 1px solid; border-left: #000000 1px solid;
border-bottom: #000000 1px solid;">
&nbsp;
</td>
<%  }%>
<%} %>
</tr>
</table>
</form>
Recall that the blocks are used to emit server side code on the client side. What is happening here is that when the Page HTML is being generated, the [for] loop code gets executed. Since we declared barCount & maxCount as public variables, these are accessible in the code block. Depending on these values, an appropriate number of elements are inserted in the code, which eventually gives us the output graph. Please note that the script blocks are executed during the [RENDER] phase of the page. It means that if you are setting the variable values multiple times during your page lifecycle, the value set just prior to Render will be used. Keep in mind the following points about client code blocks :  This mechanism was put in place for backward compatibility with ASP.  Only public variables / properties / methods are accessible in the client code blocks.  Should be used only where appropriate. Check out the actual source code here. View the running application here. Happy Coding !!

Thursday, November 29, 2007

How to refer a server side control inside client side script

Referencing a control inside a user control / master page on the client side is a little complicated because Asp.Net "fudges" the ID of all controls rendered as part of a user control, or a master page template. We'll look at the "why" of this a little later in the article, but let us look at the "how" of it with an example. Create a simple User Control which has a single button btnInput :

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="UsrCtrl.ascx.cs" Inherits="A_1_UsrCtrl" %>
<script language="javascript" type="text/javascript">
    function btnClicked(btnID)
    {
        var obj = document.getElementById("<%=btnInput.ClientID %>");
        alert('There is a button named : ' + obj.id + ' on this user control');
    }
</script>

<input type="button" runat="server" id="btnInput" value="Click Me" onclick="btnClicked()" />
Pay attention to the javascript function - we're getting the object using document.getElementById( ... ), and displaying an alert box with the ID of our button. Embed this on an Aspx page, and run it. When the button is clicked, you get the following error : So what happened ? To understand, view the source of your page (you can do this by right click on the page --> View Source). Look at our button control in the rendered HTML, it looks something like this :
<input name="UsrCtrl1$btnInput" type="button" id="UsrCtrl1_btnInput" value="Click Me" onclick="btnClicked()" />
What happened ? The ID of the User Control has been prepended to the front of the button's ID. You might be wondering, "why on earth would asp.net fudge the ID of controls". To understand why, imagine a situation where you have created five different user controls, each having a label named "btnInput". When you put all these five user controls on a single page, and if Asp.Net renders all the controls as is, we would have five buttons on the same webpage, having the ID "btnInput". This would not be acceptable, since each HTML element on a web page should have a unique ID. But in this case, when the page renders, there would be no way to distinguish which button is from which usercontrol, since all of them have the same ID. That is the reason for the following rule in Asp.Net : "If a control is embedded in a user control / master page, it's ID property is prepended with the parent user control's ID when the page is rendered". That is the reason that the user control's ID has been prepended to the button's ID in our above example. But this behavior creates problems in client side script. You would normally try to refer to a control as
document.getElementById([control id]
But in our case, you can't just use the control's ID. You have to use the actual "fudged" ID of the control. To account for this behavior in our client side javascript, we can use a handy asp.net control property called "ClientID". This property is always set to the actual ID of the control on the rendered page. Which means that if the control is not inside a user control, the ClientID would be same as the ID, but if the control is inside a user control, the ClientID will be [User Control ID]_[Control ID]. For e.g. in our case, ClientID will be set to "UsrCtrl1_btnInput". Here's how to use it to get the actual ID of a page webcontrol :
    function btnClicked(btnID)
    {
        var obj = document.getElementById("<%=btnInput.ClientID %>");
        alert('There is a button named : ' + obj.id + ' on this user control');
    }
Look at the highlighed code. The magic here is the <%= ... %> block. What this does is that when the page is rendered(as html), it executes the code between the
 <%= ... %> 
, and places the result of the embedded code in its place. Please note the fact that the code blocks are evaluated after the Render page method fires. So, if you are changing the server side variable in different methods, (say, page_load, preRender, and some event handler), only the most recent value will be reflected on the client side (in our case, the value set in the preRender method). The above highlighted line looks like the following when the page is rendered :
var obj = document.getElementById("UsrCtrl1_btnInput");
Once you have this, you can access the control on the client side just like any other normal control. Interestingly, the <%= %> blocks are not limited to only control properties. You can even call the page's public methods, and the returned values will be substituted in the output HTML. For e.g., let's say we have a C# method codeBehindMethod() that always returns "TEST". The following line is gonna show an alert box with the message "TEST".
alert(<%= codeBehindMethod() %>);

Until now, we saw how to access a server side variables in client side script. However, it is also possible to run your C# code on the client side. This can be put to use to achieve some pretty sleek functionality. In my next post, we'll see how to execute C# code on the client side to achieve convenient results.

Friday, November 23, 2007

How to pass values from popup window to calling page

Passing values from popup window to parent page can get tricky sometimes, especially if you are attempting to do heavy duty stuff in the popup window. The best way to do this is to create hidden variables on the parent page, and populate these from the popup window with whatever values need to be passed to the parent. As usual, let us take an example. Suppose we have the following requirement : 1. Create an .aspx page, that opens a popup window on a button click. 2. The popup window that opens up should have a user information form that collects UserName, Address, Phone No. 3. Upon filling up the details, the user shall click a button that closes the window and passes the information to the main page. 4. The user information from the popup window should be displayed on the main page now. So basically, we need to pass values from the popup window to the parent page. Let us look at the parent page code first :

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>

<!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>Untitled Page</title>

    <script language="javascript" type="text/javascript">
        function openWindow()
        {
            window.open('/website3/testpage.aspx', null, 'height=200,width=400,status=yes,toolbar=no,menubar=no,location=no');
            return false;
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input type="button" runat="server" onclick="openWindow();" value="Click Me" />
            <b>Information from the popup window :</b>
            <br />
            <label>
                UserName :
            </label>
            <label id="lblUName">
            </label>
            <br />
            <label>
                Address :
            </label>
            <label id="lblAddress">
            </label>
            <br />
            <label>
                Phone no :
            </label>
            <label id="lblPhone">
            </label>
        </div>
    </form>
</body>
</html
Run the page and click on the button to open a popup window that shows the a page TestPage.aspx. This is the aspx page for our popup window. As per the requirements, this should have some data entry fields in which the user can enter values, and also a button that closes the window. Upon window close, the user-entered values should be persisted to the main page. Look at the code below :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestPage.aspx.cs" Inherits="TestPage" %>
<!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>Popup Window</title>
    <script language="javascript" type="text/javascript">
        function passValues()
        {
            ;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <label>
                UserName :
            </label>
            <input type="text" id="txtUName" />
            <br />
            <label>
                Address :
            </label>
            <input type="text" id="txtAddress" />
            <br />
            <label>
                Phone No. :
            </label>
            <input type="text" id="txtPhone" />
            <br />
                        <input type="submit" onclick="passValues(); window.close()" value="Submit" />
        </div>
    </form>
</body>
</html>
Note that we have created the function passValues but have not yet implemented it. Now run the main page, you should see something like this : So much for laying the groundwork. The tough task now is to propagate the values that the user enters in the popup window, to the parent page. As you can guess, we'll have to first access the popup window's parent window, and once we have the parent window reference, we can get the required elements by doing the following : [parentWindow Object].document.getElementById('lblUName'); To access an element on the parent window, you can do the following : window.opener.document.getElementById('lblPhone').innerText = 'xyz'; Look at the code below to get a better idea of what we are talking about :
        function passValues()
        {
            window.opener.document.getElementById('lblUName').innerText = document.getElementById('txtUName').value;
            window.opener.document.getElementById('lblAddress').innerText = document.getElementById('txtAddress').value;
            window.opener.document.getElementById('lblPhone').innerText = document.getElementById('txtPhone').value;
        }
This function grabs the window's parentWindow's document object, and searches for the required elements (lblUName, lblAddress, lblPhone) therein. It assigns these objects the values from the popup window textboxes. Now to complicate things a little bit further, let us try to access elements of the parent page that are in an iFrame. Here's the (modified) parent page :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>

<!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>Untitled Page</title>
.
.
.
.
            <label>
                Phone no :
            </label>
            <label id="lblPhone">
            </label>
        </div>
        <iframe src="HTMLPage.htm" width="400px" height="200px"></iframe>
    </form>
Confused ? Review the screenshot below to jog your memory : Our goal here is this : -- When the user clicks the Submit button on the popup window, the UserName, Address and Phone no. fields should be displayed on the parent page. In addition to that, the UserName should also be propagated to the iFrame's page's [lblPopupValue] label control. To achieve this, we would have to access the [frames] collection of the parent window object. To cut a long story short, here's the magical line of code : window.opener.frames(0).document.getElementById('lblPopupValue').innerText = 'blah blah'; Pardon the blah blah. Here's the complete code :
        function passValues()
        {
            window.opener.document.getElementById('lblUName').innerText = document.getElementById('txtUName').value;
            window.opener.document.getElementById('lblAddress').innerText = document.getElementById('txtAddress').value;
            window.opener.document.getElementById('lblPhone').innerText = document.getElementById('txtPhone').value;   
            window.opener.frames(0).document.getElementById('lblPopupValue').innerText = document.getElementById('txtUName').value;
        }
` And that's it. To summarize, we've successfully opened / closed a popup window, passed values to the parent window, and passed values to an iFrame embedded in the parent window.

Monday, November 19, 2007

How to call a javascript method from the server side code

Calling a javascript method from a server side control requires adding an attribute to the control. Let us take an example -- Suppose we have a simple asp.net button on our web page, and want to display a javascript alert when this button is clicked. Our first instinct would be to put the script in the .aspx page itself, like this :

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>

<!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>Javascript Experiment</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Button ID="btnClickMe" Text="Click Me" runat="server"     OnClick="alert('Clicked');" />
    </div>
    </form>
</body>
</html>
Try compiling it (in VS 2005), and you get the following error : error CS1012: Too many characters in character literal Why ? Because the [OnClick] here refers to the serverside OnClick event(the one you define in your code-behind). It does not refer to the javascript onclick event of the button. So how do you "tell" the server-side button control to call the client side onclick event ? By writing the following in your code-behind :
btnClickMe.Attributes.Add("onclick", "alert('Clicked');");
Recall that each asp.net server control is rendered as an HTML element on the page. So before including the above line in our code, here's how our button is rendered :
<input type="submit" name="btnClickMe" value="Click Me" id="btnClickMe" />
As you can see, our button [btnClickMe] is rendered as an <input /> html element. It has four attributes : type, name, value, and ID. When we add the Attributes.Add method to our code-behind, here's how the button looks :
<input type="submit" name="btnClickMe" value="Click Me" onclick="alert('Clicked');" id="btnClickMe" />
Note the [onclick] attribute rendered here. This basically causes the "alert" to be shown when the button's onclick event is raised (in other words, when the button is clicked). You can further extend this example to call a javascript method that does something meaningful on the button click. Guess it can look something like this :
btnClickMe.Attributes.Add("onclick", "someMeaningfulMethod();");
So to summarize, we don't directly call the javascript method from the server side code. Instead, we add attributes to the control so that when the control is rendered (as html) on the browser, it also contains the attributes (event handlers, in this case) we have added.

Saturday, November 17, 2007

How to access a client-side control in asp.net code behind file

Accessing client-side variables/elements on the server side is not a straightforward affair. This is because the elements you create using javascript are not "server" controls, so you cannot directly access them in your code behind code like regular asp.net server controls (by the way, server controls are controls that have the runat="server" attribute set.) To achieve this functionality, we use hidden controls. Hidden controls are HTML controls that remain "hidden" on the page. In other words, you can assign a text value to the hidden controls (just like label, textbox etc.), but their contents are not rendered on the screen. By creating hidden controls with runat="server" set, we can access them both on client-side and server-side code. Let us take an example. Suppose we have a simple .aspx page which has three elements : 1. An Asp.Net ListBox control, 2. A button for adding new options to the listbox, and 3. A button for posting back the page. Here's what it looks like :

<%@ 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>Untitled Page</title>
    <script language="javascript" type="text/javascript">
        function myMethod()
        {
            var listbox = document.getElementById('ListBox1');
            var newElement = document.createElement('option');
            newElement.text = 'Test';
            listbox.options.add(newElement);
            window.event.returnValue = false;
        }       
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input id="Submit1" onclick="myMethod();" type="submit"
                value="Add Element" />
            <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
            <input id="Submit2" type="submit" value="PostBack Page" />
        </div>
    </form>
</body>
</html>
Run the above page. Observe that on clicking on the first button, our javascript method "myMethod()" successfully adds new elements to the listbox. However, as soon as you postback the page using the second button, the elements that you added are lost. Why ? The reason for this is that although we have added the controls on the client-side, the viewstate variable on our page hasn't changed at all. It still says that the page has only one server control - the Listbox. So while processing the page upon postback, when asp.net constructs the "tree" of all controls on the page, it does not realize that there have been a few listbox elements added to the page on the client side (because the viewstate doesn't say so). Hence, when it renders back the page upon postback, it just renders an empty listbox. To get around this, we would have to make an "entry" for the new elements in the viewstate, which is not possible because viewstate is encrypted. The second option is to use a hidden variable with runat="server", and put a comma seperated list of the new listbox elements added in this hidden variable. That way, when the page posts back, we read the value in the hidden variable and accordingly add new elements to the Listbox. Here's the modified .Aspx page for this :
<%@ 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>Untitled Page</title>
    <script language="javascript" type="text/javascript">
        function myMethod()
        {
            var listbox = document.getElementById('ListBox1');
            var newElement = document.createElement('option');
            newElement.text = 'Test';
            listbox.options.add(newElement);
            document.getElementById('hdnListElements').value = document.getElementById('hdnListElements').value + ',' + newElement.text;
            window.event.returnValue = false;
        }         
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input id="Submit1" onclick="myMethod();" type="submit"
                value="Add Element" />
            <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
            <input id="Submit2" type="submit" value="PostBack Page" />
            <input type="hidden" runat="server" id="hdnListElements" />
        </div>
    </form>
</body>
</html>
Observe carefully the highlighted line. We are basically creating a comma-seperated list of all the elements added to the listbox on the clientside. On the server-side, we read these values, and populate the listbox with the newly added child elements. Here's the C# code :
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
            string str = hdnListElements.Value;
            // If the hidden variable is empty, no new elements added.
            if (!String.IsNullOrEmpty(str))
            {
                // Split the comma-seperated list into an array of strings.
                string[] strArray = str.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
                foreach (string sTemp in strArray)
                {
                    // foreach newly added element, add a ListItem to the listbox control
                    ListBox1.Items.Add(new ListItem(sTemp, sTemp));
                }
                // Clear the hidden variable, so it does not contain the currently added elements.
                hdnListElements.Value = String.Empty;
            }
    }
}
And that is it. That's a pure and simple way to access client-side variables / controls in server-side code.