ASP.NET - Populate a page with input entered from a previous page - asp.net

on my website I have an "Enroll" page where users submit some basic information, there's some basic validation on that page then the user is taken to an "Enrollment Confirmed" page (which i don't want to display the info from previous page). On the confirmation page there is link to a "Print Enrollment Confirmation" page which, on this page, I want to contain the information entered from the "Enroll" page. So basically, I want the input entered on "Page 1" put into labels on "Page 3". I've seen some examples of transferring information from "Page 1" to "Page 2" but I have an extra page users need to go through before hitting the page with their previously entered data.
Can someone give me an explanation on how I could do this without using query strings? Thank you.

You could create an class with properties for each form field then store it in the session. Then after you populate what you need on page 3 remove it from the session.
Example
Class:
<Serializable()>
Public Class Input
Private _FirstName As String = String.Empty
Private _LastName As String = String.Empty
Public Property FirstName As String
Get
Return _FirstName
End Get
Set(ByVal value As String)
_FirstName = value
End Set
End Property
Public Property LastName As String
Get
Return _FirstName
End Get
Set(ByVal value As String)
_FirstName = value
End Set
End Property
Public Sub New()
End Sub
End Class
Storing data:
Private Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim FormData As New Input()
FormData.FirstName = txtFirstName.Text
FormData.LastName = txtLastName.Text
Session("InputData") = FormData
End Sub
Retrieving it:
If Not IsNothing(Session("InputData")) Then
Dim FormData As Input = DirectCast(Session("InputData"), Input)
txtFirstName.Text = FormData.FirstName
txtLastName.Text = FormData.LastName
Session.Remove("InputData")
End If

You could use the button.postbackurl property to post the data to another page:
http://msdn.microsoft.com/en-us/library/ms178140.aspx
In the intermediary pages, you could store the data in hidden fields from page 1, so the data would be in the posted results for page 3, when another button posts the data from page 2 to page 3.
HTH.

This pretty much sums up your choices:
http://msdn.microsoft.com/en-us/library/6c3yckfw.aspx

I would store the values in hidden input fields on page 2 and if page 3 is called as a form submit, then the values will be available through Request.Form.

Related

List.Add is replacing index 0 instead of adding to the next position. Why?

I'm using ASP.NET and Visual Basic to make a custom form, used for filling in information. Once I click a button, a function gets called that takes the bits information from that form, puts them into an object, and adds that object to a list. This is being used for a sort of queued entry system, so the form will be edited and submitted multiple times.
For some reason, instead of adding the new object in the next index position of the list, it instead replaces whatever was at 0. So, there is only ever one object in the list at the time.
Here's the custom form:
Here's my custom object, which is currently placed above my _Default class:
Public Class QueueItem
Public Property _TestName As String
Public Property _ValueID As String
Public Property _MathOperator As String
Public Property _ValueInput As Integer
Public Sub New()
End Sub
Public Sub New(ByVal TestName As String, ByVal ValueID As String, ByVal MathOperator As String, ByVal ValueInput As Integer)
_TestName = TestName
_ValueID = ValueID
_MathOperator = MathOperator
_ValueInput = ValueInput
End Sub
End Class
The list is declared above my Page_Load function, inside the _Default class, and is public. Here's that list definition:
Public QueueList As List(Of QueueItem) = New List(Of QueueItem)()
And, here's what gets called when that "Add To Queue" button is pressed:
Protected Sub AddToQueueButton_Click(sender As Object, e As EventArgs) Handles AddToQueueButton.Click
'Adds a new QueueItem to the QueueList
'Values pulled from the dropdown lists in the custom form
QueueList.Add(New QueueItem() With {
._TestName = TestName.SelectedValue,
._ValueID = ValueID.SelectedValue,
._MathOperator = MathOperator.SelectedValue,
._ValueInput = ValueInput.Text
})
'Below section is for testing
Dim test1 As String = QueueList(0)._TestName
Dim test2 As String = QueueList(0)._ValueID
Dim test3 As String = QueueList(0)._MathOperator
Dim test4 As String = QueueList(0)._ValueInput
Dim testmessage As String = test1 + " | " + test2 + " | " + test3 + " | " + test4
Dim count = QueueList.Count
Dim capacity = QueueList.Capacity
Response.Write("<script language='javascript'>alert('" + testmessage + "');</script>")
End Sub
So, as you can see, I have some test variables and stuff that I'm using to make sure this is working. Any time this gets called, an object gets added to the list, I look at the count and capacity for the list, and I display all the information in an alert.
This information for the alert is always reading from index 0. So, it shouldn't matter how many times I add information to the list, 0 should stay the same, and objects should be added at 1, then 2, and so on. Right?
Well, 0 changes any time I submit new information, and neither the count or capacity never increase past the first entry. They always display as if there's only one item in the list.
Here's me running the queue entry form twice, with two different numbers on the end:
First run:
Second run:
Since I'm always reading from index 0, that number at the end shouldn't change. It should be giving me the number that's associated with the object at index 0. And, the List.Add function should make the count and capacity go up. But, none of that happens. Instead, it seems to be replacing what was at 0.
If anyone has any tips on how to fix this or can clue me in on what might be going on, that would be greatly appreciated.
Every time a request is made to your page, a new instance of your class is created to handle the request. For a post-back request, some data may be loaded - for example, the values of the fields posted to the server, and anything stored in ViewState. But data stored in fields within your page will not be persisted across requests.
The code is not replacing the item at index 0; it is adding an item to an empty list.
You need to persist your list between requests somehow. You can either store it in the Session, or put it in the ViewState.

How To Get Value of a label from a Master Page in VB.NET?

I have a label in a master page (lblUserCode) that contains the user identity code of the person logged in.
My Metrics page would need that user code to generate graphs for that specific person who logged in. Am I able to make use of the value of txtIdentity in the metrics page?
If so, how?
Thanks,
Poch
Update 1:
I tried the Master Page property approach:
I placed this in the Master Page:
Public Property ptyUserCode()
Get
Return lblUserCode.Text
End Get
Set(value)
lblUserCode.Text = value
End Set
End Property
The ptyUserCode and value have green lines under them with a message saying that "Property without an 'As' clause; type of object assumed."
In the Metrics page, I placed this:
Dim strUserCode = CType(Page.Master, Site).ptyUserCode
But it has a blue line underneath saying that 'ptyUserCode' is not a member of 'Site'. And true enough, my graph doesn't work :(
Update 2:
Placed this in the Master Page:
Private _UserCode As String = lblUserCode.Text
Public Property ptyUserCode() As String
Get
Return _UserCode
End Get
Set(value As String)
_UserCode = value
End Set
End Property
And then this in the Metrics page:
Dim strUserCode = Master.ptyUserCode
It gives me a page error, though :( it says that "'ptyUserCode' is not a member of 'System.Web.UI.MasterPage'."
:(
You can do something like
Private _UserCode As String;
Label lblUserCode = Page.Master.FindControl("lblUserCode");
//_UserCode = lblUserCode.Text
Best Regards
on you code-behind:
dim foo as string
foo = txtIdentity

VB.Net exception: Object reference not set to an instance of an object

I'm currently working on coding a web page for a school project. This site is supposed to be a simple online store where people can order prints of artwork. The specific page I'm working on has a Drop Down List (ddlArt) that is bound to my database and displays a list of the different art pieces available. When the user selects one of the items, all the information on that item is pulled from the database and displayed on the page in a variety of labels and such. The only thing is that I'm getting a null reference exception error saying "Object reference not set to an instance of an object" when I go to try to run the page. I got the same error on a homework assignment earlier in the year and managed to get it fixed, but I can't remember what I did and I can't get help from school until next week, so I thought I'd try my luck on here. Here's my code:
Private selectedArt As Art
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ddlArt.DataBind()
End If
selectedArt = Me.GetSelectedArt
lblArtID.Text = selectedArt.ArtID()
lblArtName.Text = selectedArt.ArtName()
lblCaption.Text = selectedArt.Caption()
lblDescription.Text = selectedArt.Description()
imgArt.ImageUrl = "~/images/" & selectedArt.FileName()
End Sub
Private Function GetSelectedArt() As Art
Dim artTable As DataView = CType(SqlDataSource1.Select(DataSourceSelectArguments.Empty), DataView)
artTable.RowFilter = "ArtID = '" & ddlArt.SelectedValue & "'"
Dim artRow As DataRowView = artTable(0)
Me.imgArt.ImageUrl = "~/images/" & artRow("FileName")
Dim art As New Art
art.ArtID = artRow("ArtID").ToString
art.ArtName = artRow("ArtName").ToString
art.Caption = artRow("Caption").ToString
art.Description = artRow("LongDescription").ToString
art.FileName = artRow("FileName").ToString
Return art
End Function
And here's the code for the Art class, in case anybody is interested:
Public Class Art
Public Property ArtID As Integer
Public Property ArtName As String
Public Property ArtType As String
Public Property Caption As String
Public Property FileName As String
Public Property Description As String
End Class
When I get the error, it highlights the artTable.RowFilter = "ArtID = '" & ddlArt.SelectedValue & "'" line in the GetSelectedArt function. I've tried comparing it to my corrected homework assignment that I mentioned, but I can't seem to find the problem. My VB is a little fuzzy because it's been awhile since I actually took the class. Any suggestions? Thanks a bunch!
If I understand your comment above correctly, on the initial page load there is nothing in the ddlArt, because the user must first choose an art type.
If that is correct, then your answer to my question is your answer.
For whatever reason (and without seeing at least the Select statement), artTbl is not getting instantiated, which is why you're seeing the Object reference not set to an instance of an object error.
One way to fix this (without knowledge of your SqlDataSource it's hard to give a precise answer) is to modify your Page Load method so that GetSelectedArt is only called when the user has selected an item from the drop down list. Right now GetSelectedArt is called every time the page loads.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ddlArt.DataBind()
Else
selectedArt = Me.GetSelectedArt
lblArtID.Text = selectedArt.ArtID()
lblArtName.Text = selectedArt.ArtName()
lblCaption.Text = selectedArt.Caption()
lblDescription.Text = selectedArt.Description()
imgArt.ImageUrl = "~/images/" & selectedArt.FileName()
End If
End Sub
However, the above modification will only prevent GetSelectedArt from being called on the initial page load. If your SqlDataSource.Select command is still returning nothing, then you're still going to have this problem.
A better solution would be to call the GetSelectedArt on the ddlArt.SelectedIndexChanged event handler. This way you'll know that you have (or should have) a valid SelectedValue from ddlArt.
Also, if you don't populate the drop down until the user selects an art type from the radio button list, why are you binding the drop down list on the initial page load (and what are you binding it to)? Or is the drop down list and detail information on a different page from the radio button list?
May be .. with ArtID as integer
artTable.RowFilter = "ArtID = " & format(ddlArt.SelectedValue)

Loading usercontrol to string and submitting the form within

What i'm doing is creating a website where the design is done i html files that are then read into the masterpage using System.IO.StreamReader.
and inside the html templates there are keywords like #USER.LOGIN#
that I replace with functions etc.
The issue is that i'm replacing #USER.LOGIN# With a usercontrol where there is a login form.
I have a function that reads the usercontrol into a string and it works.
but since the usercontrol is loaded to string alle the events are not following.
so when I submit the login form nothing nothing happends (the page posts) but cannot get any of the fields from the form...
NOTE:
i'm using url-rewriting so urls are http://www.domain.com/account/login
where account is account.aspx and login is the mode the account is in.
Code for replacing the keyword in the streamreader loop (pr line)
If InStr(line, "#USER.LOGIN#") Then
line = line.Replace("#USER.LOGIN#", vbCrLf & userfunc.GetMyUserControlHtml("uc", "account_login.ascx", "/account/login/") & vbCrLf)
End If
And the functions to read usercontrol
Public Shared Function GetMyUserControlHtml(contextKey As String, controllerfile As String, Optional ByVal formaction As String = "")
Dim myId As Guid = New Guid()
Return userfunc.RenderUserControl("~\Controllers\" & controllerfile, "", myId, formaction)
End Function
Public Shared Function RenderUserControl2(path As String, Optional ByVal formaction As String = "") As String
Using pageHolder As New Page(), _
viewControl As UserControl = DirectCast(pageHolder.LoadControl(path), UserControl), _
output As New StringWriter(), _
tempForm As New HtmlForm()
If formaction <> "" Then
tempForm.Action = formaction
Else
tempForm.Action = HttpContext.Current.Request.RawUrl
End If
tempForm.Controls.Add(viewControl)
pageHolder.Controls.Add(tempForm)
HttpContext.Current.Server.Execute(pageHolder, output, False)
Dim outputToReturn As String = output.ToString()
Return outputToReturn
End Using
End Function
How would you guyz do this?
I need the userlogin to be hardcoded in the usercontrol but still be able to place it anywhere using the template keyword.
This will also be used with other functions (newsletter signup, shoutbox etc.)
what i would suggest is register you control on the web config..
<add tagPrefix="CustomControl" tagName="LogIn" src="~/UserControls/Login.ascx"/>
you can still use "#USER.LOGIN#" but instead of replacing it with a control...
replace it with a something like this
<CustomControl:LogIn id="LogIn" runat="server"/>
this is just a quick write up.. but you could always try if it works
you can save your HTML like this istead of placing an actual "#USER.LOGIN#"
<% =GetLoginControl() %>
and then create a public function in your code behind named GetLoginControl() and return a response.write of the HTML Mark up you need

Asp.Net Button Event on refresh fires again??? GUID?

The obvious issue here is that on refresh a button event is recalled and duplicate posts are created in the database. I have read other questions on this site about the very same issue.
Apparently the answer is for every post create a GUID and check to make sure the GUID is unique? I am not really sure how to implement this.
Does that mean on refresh, it will try and create a duplicate post with the same GUID?
How do you implement a GUID into your database? Or if this is not the answer, what is?
Thank you!
The idea is that you create a unique number for the form, and when the form is posted you save this unique number in the database in the record that you are editing/creating. Before saving you check if that number has already been used, in that case it's a form that has been reposted by refreshing.
If you are updating a record, you only have to check if that record has been saved with the same unique number, but if you are adding a new record you have to check if any other record has that number.
A Guid is a good number to use as it's very unlikely that you get a duplicate. A 31 bit random number that the Random class can produce is also pretty unlikely to give duplicates, but the 128 bits of a Guid makes it a lot more unlikely.
You don't have to create the Guid value in the database, just use Guid.NewGuid() in the code that initialises the form. You can put the Guid in a hidden field in the form. In the database you only need a field that can store a Guid value, either a Guid data type if available or just a text field large enough to hold the text representation of the Guid.
You can use the ToString method to get the string representation of a Guid value (so that you can put it in the form). Using id.ToString("N") gives the most compact format, i.e. 32 hexadecimal digits without separators. Using id.ToString("B") gives the more recognisable format "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}". To get the Guid back from a string (either format), you just use new Guid(str).
Here's a RefreshValidator control that I use. Just drop it on your page, and check Page.IsValid before saving to the database. You can add an error message like other validators, or catch the Refreshed event if you want to do something special. Since it's a Validator, GridViews and the like will already take notice of it - except for Delete or Cancel actions (yeah, I have a custom GridView that solves that too...)
The code is pretty simple - store a GUID into ControlState, and a copy in Session. On load, compare the 2. If they're not the same - then it's a refresh. Rinse, repeat, and create a new GUID and start over.
''' <summary>
''' A validator control that detects if the page has been refreshed
''' </summary>
''' <remarks>If <see cref="SessionState.HttpSessionState" /> is not available or is reset, validator will return Valid</remarks>
Public Class RefreshValidator
Inherits BaseValidator
Private isRefreshed As Boolean
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
Page.RegisterRequiresControlState(Me)
End Sub
Protected Overrides Function SaveControlState() As Object
Dim obj As Object = MyBase.SaveControlState()
Return New System.Web.UI.Pair(_pageHashValue, obj)
End Function
Protected Overrides Sub LoadControlState(ByVal savedState As Object)
Dim pair As System.Web.UI.Pair = TryCast(savedState, System.Web.UI.Pair)
If pair IsNot Nothing Then
_pageHashValue = TryCast(pair.First, String)
MyBase.LoadControlState(pair.Second)
Else
MyBase.LoadControlState(savedState)
End If
End Sub
Private _pageHashValue As String
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
If HttpContext.Current Is Nothing OrElse HttpContext.Current.Session Is Nothing Then
isRefreshed = False
Return
End If
' Get hash value from session
Dim currHashValue As String = CType(HttpContext.Current.Session(Me.UniqueID & ":pageHashValue"), String)
If _pageHashValue Is Nothing OrElse currHashValue Is Nothing Then
' No page hash value - must be first render
' No current hash value. Session reset?
isRefreshed = False
ElseIf currHashValue = _pageHashValue Then
' Everything OK
isRefreshed = False
Else
' Was refreshed
isRefreshed = True
End If
' Build new values for form hash
Dim newHashValue As String = Guid.NewGuid().ToString()
_pageHashValue = newHashValue
HttpContext.Current.Session(Me.UniqueID & ":pageHashValue") = newHashValue
End Sub
Protected Overrides Function ControlPropertiesValid() As Boolean
Return True
End Function
Protected Overrides Function EvaluateIsValid() As Boolean
If isRefreshed Then OnRefreshed(EventArgs.Empty)
Return Not isRefreshed
End Function
Protected Overridable Sub OnRefreshed(ByVal e As EventArgs)
RaiseEvent Refreshed(Me, e)
End Sub
''' <summary>
''' Fires when page is detected as a refresh
''' </summary>
Public Event Refreshed As EventHandler
End Class

Resources