Thursday, March 22, 2012

What is the best way to pass values from one page to the next?

I am aware of Session, Cookies, QuesryStrings, etc. . but I would like a way to pass values that I get from user text input or from databases where I store the values in to variables to another page easier than that.

I tried working with the Server.Transfer("page.aspx") and then on the other page, I call the Request.Form("Control I want to get value from") but it seems that I cannot get the values.

For instance, I have a textbox1 on page1.aspx. The user enters in a value and hits the submit button which calls the Server.Transfer("page2.aspx"). In the Page_Load of page2.aspx, I want to render on the page the value of the textbox1. I call the Request.Form("textbox1") in a code render block like so. <%= Request.Form("textbox1") %>.

The value does not show. Any ideas, or is there really no way to pass values from page to page other than what I listed above? Thanks for your time.Try the following:

In page1:


Server.Transfer("page2.aspx?text1=" & TextBox1.Text)

In Page2:


<%= Request.QueryString("text1") %>

You could have more values passing from one page to another with something like this:


Server.Transfer("page2.aspx?text1=" & TextBox1.Text & "&text2=" & TextBox2.Text)

In page2 you'd use the Request.QueryString with the value you want.
but is there a way to use not use the querystring method? I eventually will have a lot of values and I want to keep the querystring to more important values. Also, what is the benefit of the Server.Transfer method if your just going to use a querystring? Why would I just go with a Response.Redirect?
> I tried working with the Server.Transfer("page.aspx") ... but it seems that I cannot get the values.

You need to use Server.Transfer( "page.aspx", true ) ... the true parameter instructs that the QueryString and Form collections are preserved.

SeeHttpServerUtility.Transfer Method (String, Boolean)
I also used the true value as well. Basically, I should be able to call the server.transfer("page", true) method and from the next page call any value from any control on the previous page correct?
> Basically, I should be able to call the server.transfer("page", true) method and from the next page call any value from any control on the previous page correct?

No, that's not correct.

The true parameter preserves only the QueryString and Form's Post values (such as the value of a textbox, and the checked state of a checkbox). No other control values move to the new page. So, unfortunately, you cannot "call any value from any control on the previous page".

In your original post, you already mentioned the option of a Session variable. You could also add to theContext.Items collection.

If you're hoping to preserve a lot of control values, then maybe using Server.Transfer is the wrong way to go.

For example, if you're using Server.Transfer so that many pages are "finished" or processed in the same way, you might instead create a base class for your pages.

Can you explain why you're using Server.Transfer?
Well what I really want to do is get user input from a few controls on a default.aspx page. Once the user has entered in valid input and clicks the submit button...I will redirect the user to another page...for instance say test.aspx.

In the test.aspx page I will use some of the values that the user entered to draw additional values from a database. Some of the other controls that the user inputed values into, I will manupipulate and eventually display everything to the user in a nice clean format.

You see, I need to keep the values the user enters, but I dont want to use the QueryString. I have been accomplishing this using the Session variables, and then just calling a Session.Abandon after I process the database, and other value manipulations. This way I'm not hogging resources, but I figured that there has to be a better way to pass values from page to page without using the querystring or session vars.

I hope this makes more sense. Dont worry about processing the database or the other manipulations, I just need the values that the user enters from textboxes, and some radio buttons to test if they are true or false. Thanks for the help! :)
> I have been accomplishing this using the Session variables, and then just calling a Session.Abandon ...

This would be an apt time to use theContext.Items collection.

Whereas a Session variable lasts for the entire session (obviously :)... the Context.Items only last while processing this single request. After the Response has been sent, the Context.Items are disposed of ... so no need for you to explicity Abandon them.

As an example, here's a page that collects the user's login name and password, and also two items of trivia. It then adds the items of trivia to the Context.Items collection, before using Server.Transfer to pass processing to another page.

ContextSend.aspx

<%@.Page language="vb" Debug="true" %>
<html>
<head>
<title>Context - Send Items</title>
<script runat="server"
Sub Submit_Click(sender as Object, e as EventArgs)
If Username.Text = "jdub" And Password.Text="12" Then
HttpContext.Current.Items.Add( "colour", Colour.Text )
HttpContext.Current.Items.Add( "undies", Undies.Text )
Server.Transfer( "contextreceive.aspx" )
Else
Prompt.Text = "Invalid login credentials."
End If
End Sub

</script>
</head>
<body>
<form runat="server">
<p>Please enter your username and password.</p>
<p>Username: <asp:Textbox id="Username" runat="server" /></p>
<p>Password: <asp:Textbox id="Password" runat="server" /></p>
<p>Please enter your favourite colour.</p>
<p><asp:Textbox id="Colour" runat="server" /></p>
<p>Boxers or briefs?</p>
<p><asp:Textbox id="Undies" runat="server" /></p>
<p><asp:Button id="Submit" text="Submit" onclick="Submit_Click" runat="server" /></p>
<p><asp:Label id="Prompt" runat="server" /></p>
</form>
</body>
</html>

And here is the page that picks these items out of context, and displays them, following the Server.Transfer:

ContextReceive.aspx

<%@.Page language="vb" Debug="true" %>
<html>
<head>
<title>Context - Recieve Items</title>
<script runat="server"
Sub Page_Load(sender as Object, e as EventArgs)
Message.Text = "Your favourite colour is: " + HttpContext.Current.Items( "colour" )
Message.Text &= "<br />"
Message.Text &= "And you wear: " + HttpContext.Current.Items( "undies" )
End Sub

Sub Move_Click(sender as Object, e as EventArgs)
Response.Redirect( "contextlost.aspx" )
End Sub

</script>
</head>
<body>
<form runat="server">
<p><asp:Label id="Message" runat="server" /></p>
<p><asp:Button id="Move" text="Move On" onclick="Move_Click" runat="server" /></p>
</form>
</body>
</html>

At the end of this page, is a button that causes a Response.Redirect. Now this causes a fresh request for a page, so the previously held Context.Items should have been disposed. Indeed, if you run these samples, the items have been lost.

ContextLost.aspx

<%@.Page language="vb" Debug="true" %>
<html>
<head>
<title>Context - Check Items</title>
<script runat="server"
Sub Page_Load(sender as Object, e as EventArgs)
Message.Text = "Your favourite colour is: " + HttpContext.Current.Items( "colour" )
Message.Text &= "<br />"
Message.Text &= "And you wear: " + HttpContext.Current.Items( "undies" )
End Sub

</script>
</head>
<body>
<form runat="server">
<p><asp:Label id="Message" runat="server" /></p>
</form>
</body>
</html>

In summary, I think that using the Context.Items collection is as simple as you can get.
To store a value:

 HttpContext.Current.Items.Add( "colour", Colour.Text )
To receive the value:
 HttpContext.Current.Items( "colour" )
And there's no need for you to handle disposing of the objects ... as this is automatically done once your app has sent its Response.

How's that?
I just realised that my example was poor.

I was only adding to Context.Items the values in the textboxes ... which would be preserved anyway using Server.Transfer( "page.aspx", true ).

However, into Context.Items you can also add values that would not otherwise be preserved with Server.Transfer. For example:

 If User.IsAuthenticated Then
If User.Name = "jdub" Then
HttpContext.Current.Items.Add( "role", "Developer" )
Else
HttpContext.Current.Items.Add( "role", "User" )
End If
Server.Transfer( "contextreceive.aspx" )
End If

Since this Role value is determined by application logic, it would not be within the QueryString or Forms values. However, we can use our Context.Items collection to store this value.
Ok, thats sounds simple enough. Can you do me a favor and explain to me exactly the benefits of the Server.Transfer Method vs. just a Response.Redirect?
Server.Transfer works only for .aspx pages in the same application and passes the 'state' of the page through to the next page. That means that the posted data etc will become available in the target page as well after the Server.Transfer call. Response.Redirect can be compare with a simple hyperlink but then server-side and does not perform this task.
The best description I have seen of the relative merits of Server.Transfer and Response.Redirect is the following:
Managing ASP.NET Navigation

Read that, and ask if you have any questions...

0 comments:

Post a Comment