ASP.Net dropdown list - multiple postback - asp.net

I have some inconsistent behaviour with a drop down list.
When it postback and the selected index is 1, it goes through and works as it should, gets the data, builds the UI, and writes everything to the screen.
if the selected index is 2 then it goes through the BuildUI() method, and then goes through the loop again thinking that the selected index is 0 and then doesn't build the UI.
this is the code
Protected Sub Page_Complete() Handles Me.LoadComplete
If _IsAuth = True Then
'if user is authorised to use the application, and the drop down menu has UK or GE
'selected then the the UI will be build for the user.
If Page.IsPostBack And ddlCharterVersion.SelectedIndex > 0 Then
BuildUI()
'once the UI has been built the dropdown list is to be hidden
ScriptManager.RegisterStartupScript(Me, GetType(Page), "ddlCharterVersion", "$('#paymentType').hide();", True)
Else
'if the user is not authorised they are passed a message showing that they are not authorised from the master
'page and the panel holding the divs and information will be hidden
ScriptManager.RegisterStartupScript(Me, GetType(Page), "hidePayments", "$('#panelHead').hide();", True)
End If
End If
End Sub
Protected Sub ddlCharterVersion_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ddlCharterVersion.SelectedIndexChanged
ddlCharterVersion.Enabled = False
End Sub
And this is the dropdown on the page.
<div class="col-md-10 pull-left "><asp:dropdownlist runat="server" width="200px" id="ddlCharterVersion" AutoPostBack="True">
<asp:ListItem Value="-- Select Charter Version -- ">-- Select Charter Version -- </asp:ListItem>
<asp:ListItem Value="UK">UK</asp:ListItem>
<asp:ListItem Value="GE">GE</asp:ListItem>
</asp:dropdownlist></div>
When debugging the application I don't hit any errors that should cause the page to postback.
what puzzles me the most is that selected index position 1 works fine, position 2 does not.
If anyone can see directly what the issue is I would be very grateful for your assistance.
--update--
-- update 2 --
when debugging this, I never hit any of the exceptions, and have a breakpoint on each of them and none of them are ever hit.
Protected Sub BuildUI()
'gets the next record for payment
GetNextRecordForPayment()
If noRecords = False Then
'if there are records, concatenate the list of payments into one row in a list
ConcatenateListOfPayments()
''write the records to the UI
writeRecordsToUI()
End If
End Sub
Protected Sub GetNextRecordForPayment()
Try
''if a user already has a record locked and has refreshed the page for any reason
''get this record back until they pass it to the excptions queue or validate for payment
'UserHasRecordLocked is returned as an object. Either as the contactId of the locked record or False
Dim UserHasRecordLocked = CheckForLockedRecord()
Dim lockedRecord As Long
Dim contactIdParam As New SqlParameter("#LockedRecord", SqlDbType.BigInt)
Dim charterVersionParam As New SqlParameter("#CharterVersion", SqlDbType.VarChar)
charterVersionParam.Value = ddlCharterVersion.SelectedValue
'check the type of object of UserHasRecordLocked
If UserHasRecordLocked.GetType = GetType(Long) Then
'if it has a record then assign the value of UserHasRecordLocked
'to the sqll parameter.
contactIdParam.Value = UserHasRecordLocked
Else
'else give it a default value
contactIdParam.Value = 99999
End If
'place all parameters into a list object of sql parameter
'this has been done this way so that you dont have to be
'precious or careful of where you place your parametss
Dim listOfParam As New List(Of SqlParameter)
listOfParam.Add(contactIdParam)
listOfParam.Add(charterVersionParam)
''gets all records due to be paid
Dim dt As DataTable
'get the first payment \ contact back in a datatable.
'brings back all the parts of the payment, ie redress, d&i, hmrc deductions
'and later concatenates them into one line
dt = DataAccessLayer.FindRecords(listOfParam, _charterPayments, "dbo.usp_getFirstRecordForPayment")
If dt.Rows.Count = 0 Then
noRecords = True
'if there are no records inform the user that there are no payments to be made this day.
ScriptManager.RegisterStartupScript(Me, GetType(Page), "noPayments", "$('#noPayments').modal();", True)
Exit Sub
End If
'build a list of payments using a payee class
BuildListOfPayments(dt)
'using MoreLINQ to get the First or Default record to get the most basic of information out.
Dim paymentInfo = listOfPayments.FirstOrDefault()
''if payment is an IVA, C&R or Deceased Case this will be thrown to the exceptions for manual handling.
If paymentInfo.isException = True Then
'record the exceptions
Dim recorded = RecordNewException(paymentInfo.ContactId, paymentInfo.ContactPartId, paymentInfo.ExceptionReason, True)
If recorded = True Then
'post the page back to get the next record and start the loop again
Response.Redirect(Request.RawUrl, False)
Context.ApplicationInstance.CompleteRequest()
End If
End If
Try
'set the class level variable
_PaymentCategory = paymentInfo.Category
Catch ex As Exception
Dim recorded = RecordNewException(paymentInfo.ContactId, paymentInfo.ContactPartId, "Cannot match complaint against a category type", True)
If recorded = False Then
Response.Redirect(Request.RawUrl, False)
Context.ApplicationInstance.CompleteRequest()
End If
End Try
'lock the record so that no other user can be working on this at the same time
LockRecord(dt)
If paymentInfo.charterVersion = "GE" Then
'if the payment is coming from GE Charter then complete various checks
checkGeCharterPayments(paymentInfo)
ElseIf paymentInfo.charterVersion = "SANUK" Then
'if the payment is coming from GE Charter then complete various checks
checkSanCharterPayments(paymentInfo)
Else
Exit Sub
End If
Catch sqlEx As SqlException
PassToErrorHandler(sqlEx, System.Reflection.MethodInfo.GetCurrentMethod().ToString(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name)
Catch ex As Exception
PassToErrorHandler(ex, System.Reflection.MethodInfo.GetCurrentMethod().ToString(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name)
End Try
End Sub

Related

How can I store the data in memory and use by the other Button click event to display the data?

Here is the code, but the datatable is NULL in ButtonExport click event, how can i pass the DataTable to Sub ButtonExport_Click ? I dont want to store in Session as the data is too big
Here is the class clsGlobalVarriable
Public Class clsGlobalVariable
Private _gdt As DataTable
Public Property globalDataTable As DataTable
Get
Return _gdt
End Get
Set(ByVal value As DataTable)
_gdt = value
End Set
End Property
End Class
Here is the From frmTest code:
Public Class frmTest
Inherits System.Web.UI.Page
Private gdt As New clsGlobalVariable
Protected Sub ButtonInactivePC_Click(sender As Object, e As EventArgs) Handles ButtonInactivePC.Click
Try
Dim func As New clsFunction
Dim command As String = "Get-ADComputer -Filter { OperatingSystem -NotLike '*Windows Server*'} -Property * | select Name, CanonicalName, operatingSystem, LastLogonDate, Description, whenChanged | Where {($_.LastLogonDate -lt (Get-Date).AddDays(-90)) -and ($_.LastLogonDate -ne $NULL)}"
Dim arr As New ArrayList
arr.Add("Name")
arr.Add("CanonicalName")
arr.Add("operatingSystem")
arr.Add("LastLogonDate")
arr.Add("whenChanged")
arr.Add("Description")
gdt.globalDataTable = func.PSObjectToDataTable(command, arr)
Me.GridView1.DataSource = gdt.globalDataTable
Me.GridView1.DataBind()
Catch ex As Exception
Me.LabelDebug.Text = "Button Click" + ex.Message
End Try
End Sub
Protected Sub ButtonExport_Click(sender As Object, e As EventArgs) Handles ButtonExport.Click
Dim func As New clsFunction
Dim dt As New DataTable
dt = (DirectCast(Me.GridView1.DataSource, DataTable))
Me.LabelDebug.Text = "Global Data Table Count = " & dt.Rows.Count
End Sub
When working with webpages that show data to the user, and the user takes some action on that data you either need to store the data somewhere in their computer, your computer (the server) or rely on the fact that it's still stored in the computer you got it from. As a process you have undertaken:
You generate a grid from querying AD
You send the grid to the customer's computer - so it's stored there as a visual representation (and maybe also ViewState)
It's still stored in AD, where you got it
You could also store it locally on the server somehow - Session, DB, text file, whatever
Decide on which of these to use when the user clicks Export:
Dig it out of the viewstate or other data that was sent to the user - for this you'll have to code things up so it comes back from the user
Get it out of AD again - simple to do; you did it once and sent it to the user in HTML. Getting it again and sending it to the user again this time as a CSV isn't really any different from the first time you did it
Restore it from wherever you kept it on the server
Choose the first if your user is going to modify the data or choose to export only some of it - the data he sends back to you should indicate which bits he wants exporting.
Choose the second option if you want an easy life, and it's just a straight export, no editing or subset of data. Write one method that gets the data out of AD and then use it in either place, one to form HTML/fill a grid, in the other to send a file to the user. Don't get hung up on "well I already got this data once, it's a waste to get it again" - no-one writes a Login Page and thinks "i'll only ever look up a user from the DB once, then get the server to remember the login data forever more and use it next time there is a login request" - they store the data in the db, and look it up every time there is a login. DBs store data and perform the same queries over and over again. This is no different
You probably wouldn't choose the third option, for reasons already mentioned
I decided to use alternative for the Excel Export, i am not going to pass the DataTable, instead i pass the GridView to the Export to Excel function
Add the following sub right after Page_load, this is to avoid the GridView error
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
End Sub
Here is the Code:
Public Sub ExportFromGridview(ByVal gv As GridView, ByVal response As HttpResponse
response.Clear()
response.Write("<meta http-equiv=Content-Type content=text/html;charset=utf-8>")
response.AddHeader("content-disposition", "attachment;filename=" & Now & ".xls")
response.ContentType = "application/vnd.xls"
Dim stringWrite As System.IO.StringWriter = New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
gv.RenderControl(htmlWrite)
response.Write(stringWrite.ToString())
response.End()
End Sub

setting debug="false" in web.config

i am having this problem if i set debug=false in web.config file.
i had a treeview where all the nodes are loaded dynamically from code pagehide during Page_Load event
if i set debug="true" this works fine if i add another node form a button and so on.
But if i set it to false. nodes are loaded correctly during If Not IsPostBack Then if i add a new node, it will show correctly but if there is another postback,the newly added button will be disappeared and data are loaded from the first postback and i have to close the web and reopen again to load the new nodes to load.
the data will always remains at the first postback if i set debug to false.
anyone know why i am not getting new data from subsequent postback instead of first postback if i set debug to false?
please take note that i only having this issue on internet explorer 11. chrome and firefox i does not have this issue .
below is my code
If Not IsPostBack Then
Try
masternode = New TreeNod
masternode.Text = "Scale Management"
masternode.Value = "-4"
sendscalenodes.Nodes.Add(masternode)
loadNodes()'load all nodes on pageload
Catch ex As Exception
End Try
End If
End Sub
Protected Sub btndepadd_Click(sender As Object, e As EventArgs) Handles btndepadd.Click
'add nodes code here
loadNodes()'reload all nodes to refresh the tree view
End Sub
Sub loadNodes()
DepGr1.Nodes.Clear()
dbconnection.connect()
masternode = New TreeNod
masternode.Text = "Data Management"
masternode.Value = "Data Management"
masternode.SelectAction = TreeNodeSelectAction.None
DepGr1.Nodes.Add(masternode)
Dim dr As SqlClient.SqlDataReader
Dim dr2 As SqlClient.SqlDataReader
Dim sql2 As String = Nothing
sql = "select * from [data group] where DG_parent=-3"
dr = dbconnection.dr(sql)
Do While dr.Read
parentnod = New EleapTreeNod
parentnod.Text = dr.Item(4)
parentnod.Value = dr("DG_ID")
DepGr1.Nodes.Add(parentnod)
sql2 = " select * from [data group] where DG_parent=" & dr.Item(0) & ""
dr2 = dbconnection.dr(sql2)
Do While dr2.Read
childnod = New EleapTreeNod
childnod.Text = dr2.Item(4)
childnod.Value = dr2("DG_ID")
parentnod.ChildNodes.Add(childnod)
Loop
dr2.Close()
Loop
dr.Close()
dbconnection.ConClose()
DepGr1.ExpandAll()
End Sub

Evaluating whether a page is the result of a referral from a particular page

I have an Edit Profile page which allows users to change their information - currently it only allows users who have a record in the table 'userprofiles' to edit their information. I want newly registered users to be able to edit their profiles as well.
At the minute, I am using the ASP.NET membership system with the appropriate asp.net_ tables in an Access database to store user credentials. The 'userprofiles' table is a separate table which has more personal information in it. There is no link between the two tables
Here is my code behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsCrossPagePostBack Then
SeparateNewUserFunction()
Return
End If
If Not IsPostBack Then
DisplayData()
SaveConfirmation.Visible = False
End If
End Sub
And here is my DisplayData() function just if anyone was interested as to what it does:
Protected Sub DisplayData()
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
Dim newEmailAddress = ""
Dim newDescription = ""
If Not IsDBNull(profileDr("EmailAddress")) Then newEmailAddress = profileDr.Item("EmailAddress")
If Not IsDBNull(profileDr("Description")) Then newDescription = profileDr.Item("Description")
If Not IsDBNull(profileDr("AvatarURL")) Then ProfilePic.ImageUrl = profileDr.Item("AvatarURL")
description.Text = newDescription
email.Text = newEmailAddress
conn.Close()
End Sub
Rather than checking if a record exists in the 'userprofiles' table that matches the User.Identity.Name of the current user, I thought it would be easier just to evaluate whether or not the user had just been redirected from the Register.aspx page. (If this evaluation is true, then as you can see above, a separate "New User" function will be called).
That is my logic, but I have no clue if VB.NET has a "referrer" or "isReferred" expression? (at the minute as you can see I thought isCrossPagePostback might be the right thing but no luck!)
Any ideas?
You need to check whether or not a record exists and base your logic on that. That is the only right way to do it. As in:
What if you introduce a new page to handle registrations? This logic breaks.
What if you one day you retire and the next guy decides to rename the Register.aspx page? This logic breaks.
What if user hits back button and clicks the Register button again? This logic may break.
You should also consider a foreign key and unique constraint on that table, as well as using UserId instead of TravellerName. TravellerName can change, UserId will not.
... and yes you can the referring page by using HttpRequest.ServerVariables, which gets you a list of IIS Server Variables.

Checkbox list keep disabled

Trying to use checkbox lists in (calendar booking system). The checkbox should be disabled and red if there are any data in the database against the date and hour. This all work perfectly here is the code. Using vb.net
OK i found a way how to clear the checkboxes
Dim i As Integer
Dim chboxItem As ListItem
For Each chboxItem In CheckBoxListMon.Items
i += 1
If (i Mod 1 = 0) Then
chboxItem.Enabled = True
End If
Next
Protected Sub Page_LoadComplete(sender As Object, e As EventArgs) Handles Me.LoadComplete
Try
strQuery = "SELECT BookingDate, checkBoxItem, BookRegUserID,Booked FROM bookings INNER JOIN checkboxitems where checkBoxItem = BookingTime"
MySQLCmd = New MySqlCommand(strQuery, dbCon)
dbCon.Open()
DR = MySQLCmd.ExecuteReader
While DR.Read
bookDate = DR.Item("BookingDate")
bookTime = DR.Item("checkBoxItem")
bookRegID = DR.Item("BookRegUserID")
booked = DR.Item("Booked")
Dim test As String = bookTime.ToString()
Select Case True
Case bookDate = lblMonday.Text And CheckBoxListMon.Items.FindByValue(test) IsNot Nothing
CheckBoxListMon.Items.FindByValue(bookTime).Enabled = False
CheckBoxListMon.Items.FindByValue(bookTime).Attributes.Add("Style", "color: red;")
End Select
End While
DR.Close()
dbCon.Close()
Catch ex As Exception
End Try
End Sub
When the page load it would not change the ones from the database. But when i reload the page it will actually work perfect.
Where can i put the check just to be sure that they are already in the memory.
Any help will be much appreciated. Thanks all.
Petr
You need to refresh the data when another week is selected because you are using the same controls for each week. You should be able to do this in whatever control you are using to toggle through the weeks.
Page_LoadComplete can only be expedted to fire each time a page has completed loading, that is why your controls work when going to another page and back.

ASP CascadingDropDown Control Causes IE Script timeout

Before a page is loaded, I use a subroutine to link DropDownList controls together:
Private Sub CreateCascadingDropDown(ByVal category As String, ByRef parentDDL As DropDownList, ByRef targetDDL As DropDownList)
Dim CDDL As New CascadingDropDown
With CDDL
.Category = category
If Not parentDDL Is Nothing Then
parentDDL.Items.Clear()
.ParentControlID = parentDDL.ID
End If
targetDDL.Items.Clear()
.TargetControlID = targetDDL.ID
.PromptText = SharedWeb.GC_SELECTONE
.PromptValue = "-1"
.LoadingText = "Please wait..."
.ServicePath = "/ajax/InvestmentProcess.asmx"
.ServiceMethod = "GetTaxo"
End With
'Page.ClientScript.RegisterForEventValidation(CDDL.UniqueID)
targetDDL.Parent.Controls.Add(CDDL)
End Sub
When the web service method is called, it executes the following code. Based on the category, it gets the appropriate data from the adapter.
<WebMethod()> _
Public Function GetTaxo(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim log As ILog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
log.Debug("GetSegmentTaxonomy(" + category + ") -> {" + knownCategoryValues + "}")
Dim kv As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Dim adapter As New SegmentTaxonomyTableAdapters.SEGMENT_ARCHITECTURE_TableAdapter
Dim rows As DataRowCollection
Select Case category
Case InvestmentEdit.ST_SEG_ARCH
rows = New SegmentTaxonomyTableAdapters.SEGMENT_ARCHITECTURE_TableAdapter().GetData().Rows
Case InvestmentEdit.ST_LOB
If kv.ContainsKey(InvestmentEdit.ST_SEG_ARCH) Then
log.Debug("found seg architecture - > " + kv(InvestmentEdit.ST_SEG_ARCH))
rows = New SegmentTaxonomyTableAdapters.LINE_OF_BUSINESSTableAdapter().GetData(kv(InvestmentEdit.ST_SEG_ARCH)).Rows
End If
End Select
If Not rows Is Nothing Then
Dim results As New List(Of CascadingDropDownNameValue)
For Each row As DataRow In rows
log.Debug("ROW >>>> " + row("lov_label").ToString() + " : " + row("lov_cd").ToString())
results.Add(New CascadingDropDownNameValue(row("lov_label"), row("lov_cd")))
Next
Return results.ToArray
End If
Return Nothing
End Function
There are about 5 drop downs I need to link together. The top-level drop down control (myDDL) loads fine if it is the only one linked like so:
CreateCascadingDropDown("MyCat",Nothing,myDDL)
But when I link a second drop down control, Internet Explorer gives a script timeout. If I keep allowing the script to run, it just keeps giving me the prompt. If elect to discontinue running the script, I get a Method Error 12031 or Error 500 (and yes, I have the ScriptService() declaration in my web service file). Any ideas on what's causing this?
It turns out I just needed to add the following control from the Ajax Control Toolkit:
<ajax:ToolkitScriptManager ID="tsm" runat="server" />
Instead of .TargetControlID = targetDDL.ID I needed to use:
.TargetControlID = targetDDL.UniqueId

Resources