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" />

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%">
<%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;">
<% }%>
<% else%>
<%  { %>
<td style="border-right: #000000 1px solid; border-top: #000000 1px solid; border-left: #000000 1px solid;
border-bottom: #000000 1px solid;">
<%  }%>
<%} %>
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 !!