WEIRDEST ERROR EVER: ASP.NET and Firefox? - asp.net

I've always thought that server-side code is unaffected by the browser requesting it, but I've just come across an exception:
I have a button that when clicked, changes the button's CSS class (and those relative to it) and rebinds a GridView with new data. The function is this:
Private Sub lbViewUnUsed_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbViewUnUsed.Click
lbViewUsed.CssClass = "button small"
lbViewUnUsed.CssClass = "button small selected"
BindUsage(UsageBinding.UnUsed)
End Sub
In IE, this works perfectly. However, in Firefox, the BindUsage() function stops firing midway and nothing gets accomplished at all! In my frustration, I inserted Debug.Assert() statements after every line of code in the BindUsage() to see what was going on, and sure enough, the function would not go all the way through in Firefox ONLY.
The BindUsage() function is this (with the Debug assertions still in):
Private Sub BindUsage(ByVal bindWhat As UsageBinding)
Debug.Assert(False, 1)
If bindWhat = UsageBinding.Used Then
gvUsage.DataSource = sUser.GetWordsMarkedWithUsage(True)
gvUsage.Columns(0).Visible = False 'hide button column'
Else
Debug.Assert(False, 2)
gvUsage.DataSource = sUser.GetWordsMarkedWithUsage(False)
Debug.Assert(False, 3)
Dim userInfo As UserAccount.LoginInfo = UserAccount.GetUserLoginInfo
Debug.Assert(False, 4)
Dim showUsedButton As Boolean
Debug.Assert(False, 5)
showUsedButton = (userInfo.UserName.ToLowerInvariant = sUser.UserName.ToLowerInvariant)
Debug.Assert(False, 6)
gvUsage.Columns(0).Visible = showUsedButton 'show button column'
Debug.Assert(False, 7)
End If
Debug.Assert(False, 8)
gvUsage.DataBind()
Debug.Assert(False, 9)
End Sub
The above function does not make it past 5 in Firefox. I'm guessing there's some sort of problem with the assignment of the showUsedButton variable, but I can't figure out what it would be. Why would this fail only in Firefox, but not in any other browser especially since this is occurring on the server???

It's happening on the server, but you are retrieving data that was generated by the client:
UserAccount.GetUserLoginInfo
I would review your stored data and see what's different in it based on client application and see how it's handled.

Well, it's a bit of a guess, but...
What exactly does UserAccount.GetUserLoginInfo do? If I had to guess, it tries to do something browser-specific. For example, it could try and read a cookie from the client? If it does, then my next guess is that userInfo or either userInfo.UserName is null, thus throwing a NullReferenceException.
It could be that IE accepts cookies, and firefox does not. Hence no error in IE, but only in Firefox.
Again, this is guesswork, I'm not strong in VB.NET and have no idea what that UserAccount class is. Maybe if you'd give use the errormessage, it could mean some more.

Would you definitely spot if any exceptions were being thrown? If not, fix that before you do anything else.
As for why it might be browser-specific:
If it depends on what data is sent by the browser and how, then clearly the browser can change the behaviour
I believe ASP.NET renders in a browser-specific way; if your code is touching the rendering logic, it may be behaving differently depending on user agent.

Related

BackgroundWorker task blocks UI thread in my web application

Okay, I've been banging on this problem for close to 10 work hours now with no real progress to speak of. After going through multiple "solutions" offered on the web, I find myself still unable to accomplish what should be a really simple task -- pop up a modal dialog from my web application while I complete a long process I'm forcing the user to wait upon.
I've ripped out all the non-multi-threading-control aspects and am left with this bare bones structure and it still doesn't cut it:
In my ASPX file, I have two "please wait" displays, one is a DIV set up for use with bPopup, the other a DIV runat=server following the examples on BackgroundWorker. The bPopup dialog works great when used independently of any background work. But, when the background worker fires, the UI freezes until it completes, then both opens & closes the bPopup dialog as fast as it can, basically flashing the screen.
This is my code behind: I've cut it to the bare minimum to see a dialog pop up and go away again after the background task completes.
Protected Sub EditBtn_Click(sender As Object, e As EventArgs)
ScriptManager.RegisterStartupScript(Page, Page.GetType, Guid.NewGuid().ToString(), "javascript: bPopup = $('#element_to_pop_up').bPopup({ modal: true, modalClose: false});", True)
MenusBeingGenerated.Visible = True
bw = New BackgroundWorker()
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
bw.RunWorkerAsync()
End Sub
The javascript fires the bPopup, while MenusBeingGenerated is the name of the server-side DIV. The background task itself has been ripped down to just a do-nothing time-consumer.
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
For i = 1 To 40
Threading.Thread.Sleep(250)
bw.ReportProgress(i, "Running...")
If bw.CancellationPending Then
bw.ReportProgress(i, "Cancelling...")
Exit For
End If
Next
' Cleanup
If bw.CancellationPending Then
e.Cancel = True
bw.ReportProgress(100, "Cancelled.")
End If
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
StatusLabel.Text = e.ProgressPercentage.ToString & "% complete."
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
StatusLabel.Text = "Completed successfully"
ScriptManager.RegisterStartupScript(Page, Page.GetType, Guid.NewGuid().ToString(), "javascript: if (bPopup) { bPopup.close() };", True)
End Sub
When I run this code, and click the button that triggers it all there is a long pause then the screen blinks grey (the same behavior can be seen by opening and closing the bPopup from within the same button handler).
Adding breakpoints to walk through the code, I see the background task get launched via the button handler, it cycles through and the BackgroundWorker1_ProgressChanged handler gets called every quarter second, finally the BackgroundWorker1_RunWorkerCompleted method runs, and when that finishes the only page refresh finally happens (with the blink as bPopup fires & clears).
The DIV id=MenusBeingGenerated never displays, despite having been set as visible, nor does the label id=StatusLabel that resides within it ever get rendered.
Any clues what I've missed???
[ BTW, there are several questions along these lines on this and other web sites, none of the current answers apply. I've cookbooked this off several sites, thrown out multiple versions, and this is the closest I've gotten to something that works -- and it's no different than where I started: the user clicks the go button, a lot of nothing visible happens while the server churns out a new file, then the page refreshes when it's all done. ]

Button.Enabled and checkbox.Checked status erased when redirecting on event ASP.NET VB

In my register page I have a checkbox (chkAgree) next to the terms of agreement. The register (btnRegister) button is disabled until chkAgree.Checked = True. Since the registration section is toward the bottom of the page I want to redirect the user to an anchor tag during the event. I can't seem to accomplish this without one of the two objects in question losing their status. I tried creating a Session for each object and then calling them on the page load event with no luck. I am obviously doing it wrong, but could someone please point me in the right direction? btnRegister's default status is set to Enabled=False. Here are the two methods I am using
CheckedChanged:
Protected Sub chkAgree_CheckedChanged(sender As Object, e As EventArgs) Handles chkAgree.CheckedChanged
Session("Agree") = chkAgree.Checked
Response.Redirect("~/ExteriorStudentTestimonials.aspx#register", False)
End Sub
And Page_Load:
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Session("Agree") = True Then
btnRegister.Enabled = True
chkAgree.Checked = True
Else
btnRegister.Enabled = False
chkAgree.Checked = False
End If
End Sub
I have tried several different combinations of If statements but cannot figure it out without taking Response.Redirect("~/ExteriorStudentTestimonials.aspx#register", False) out.
This might be related to the fact that you're reloading the page. You might want to take a look at the following question for some ideas of how to jump to an anchor without a full redirect: Programmatically scroll to an Anchor Tag
On a different note, jumping to an anchor when the user clicks a check box doesn't sound like a very good user experience. You might consider making your form shorter.
Got it using this method similar to the ones described in the link you provided
Page.ClientScript.RegisterStartupScript(Page.GetType(),
"navigate",
"document.getElementById('register').scrollIntoView();",
True)

IE response.redirect

I ran into an extremely odd issue with IE today. IE fails every time I try to do a response.redirect more than ten times! Of course, the page works fine in FF and Chrome. Has anyone else experienced something like this?
Here are some code snippets to make sure I am not doing anything blatantly wrong...
Loop
if ( iDomain < ubound(aDomain) ) then
Response.Redirect "/home/login/a_logout.asp?site=" & strSite & "&domain=" & iDomain+1 & "&l=" & ilogout & "&s=" &sSid
end if
Array
Dim aDomain(10)
aDomain(0) = ".x.com"
aDomain(1) = "www.x.com"
aDomain(2) = "w1.x.com"
aDomain(3) = "w2.x.com"
aDomain(4) = "x.com"
aDomain(5) = "w3.corporate.x.com"
'aDomain(5) = "w4.x.com"
aDomain(6) = "w5.x.com"
aDomain(7) = "w6.x.com"
'aDomain(8) = ""
'aDomain(9) = "w8.x.com"
aDomain(8) = "w9.x.com"
aDomain(9) = "w10.x.com"
Removed context sensitive data.
Let me know if you need any other info. Thanks!
This is the default behaviour to prevent a user from being looped back to the same page infinitely.
IE8s limit is 10 requests to the same page, Chrome and FireFox I believe are 20.
And no, a different querystring doesn't constitute a new page as I found out myself.
I would highly suggest that you change this. Redirecting multiple times is a pretty bad idea.
Instead, just run whatever code is being run by your a_logout page locally. I'm assuming your clearing several cookies. Go ahead and resend all of the appropriate cookies with blank data and an expires yesterday time.
Redirecting so often is blatantly wrong. The ideal maximum number of redirects is 1. In practice it can be a lot easier to do certain tasks if you allow for more than that, but anywhere more than 5 redirects happen should be considered a bug (more than 1 on the same server or more than 3 that crosses to another server should be considered sub-optimal, but not urgent to fix).
Browsers can't depend upon servers never doing anything blatantly wrong, so after a few goes they give up to save the user from the server. Sometimes user-agents don't protect themselves in this way (not serious browsers, but it's an easy mistake to make writing a simple piece of HTTP client code). It isn't pretty.
To demonstrate just how bad this can be, consider a case where the handler for /somePath/?id=1 redirects to /somePath/?id=2 which redirects to /somePath/?id=3 and so on. For all the server knows, you've just got a more obscure version of that, and will never stop redirecting.

ASP.NET Unexpected and Different Behavior in Different Environments

I have an ASP.NET site (VB.NET) that I'm trying to clean up. When it was originally created it was written with no error handling, and I'm trying to add it in to improve the User Experience.
Try
If Not String.IsNullOrEmpty(strMfgName) And Not String.IsNullOrEmpty(strSortType) Then
If Integer.TryParse(Request.QueryString("CategoryID"), i) And String.IsNullOrEmpty(Request.QueryString("CategoryID"))
MyDataGrid.DataSource = ProductCategoryDB.GetMfgItems(strMfgName, strSortType, i)
Else
MyDataGrid.DataSource = ProductCategoryDB.GetMfgItems(strMfgName, strSortType)
End If
MyDataGrid.DataBind()
If CType(MyDataGrid.DataSource, DataSet).Tables("Data").Rows.Count > 0 Then
lblCatName.Text = CType(MyDataGrid.DataSource, DataSet).Tables("Data").Rows(0).Item("mfgName")
End If
If MyDataGrid.Items.Count < 2 Then
cboSortTypes.Visible = False
table_search.Visible = False
End If
If MyDataGrid.PageCount < 2 Then
MyDataGrid.PagerStyle.Visible = False
End If
Else
lblCatName.Text &= "<br /><span style=""fontf-size: 12px;"">There are no items for this manufacturer</span>"
MyDataGrid.Visible = False
table_search.Visible = False
End If
Catch
lblCatName.Text &= "<br /><span style=""font-size: 12px;"">There are no items for this manufacturer</span>"
MyDataGrid.Visible = False
table_search.Visible = False
End Try
Now, this is trying to avoid generating a 500 error by catching exceptions. There can be three items on the query string, but only two matter here. In my test environment and in Visual Studio when I run this site, it doesn't matter if that item is on the query string. In production, it does matter. If that third item isn't present (SubCategoryID) on the query string, then the "There are no items for this manufacturer" displays instead of the data from the database.
In the two different environments I am seeing two different code execution paths, despite the same URLs and the same code base.
The site is running on Server 2003 with IIS 6.
Thoughts?
EDIT:
In response to the answer below, I doubt it's a connection error (though I see what you're getting to), as when I add the SubCategoryID to the query string, the site works correctly (displaying data from the database).
Also, if please let me know if you have any suggestions for how to test this scenario, without deploying the code back to production (it's been rolled back).
I think you should try to print out the exception details in your catch block to see what the problem is. It could anything for example a connection error to your database.
The error could be anything, and you should definitely consider printing this out or logging it somewhere, rather than making the assumption that there's no data. You're also outputting the same error message to the UI for two different code paths, which makes things harder to debug, especially without knowing if an exception occurred, and if so, what it was.
Generally, it's also better not to have a catch for all exceptions in cases like this, especially without logging the error. Instead, you should catch specific exceptions and handle these appropriately, and any real exceptions can get passed up the stack, ideally to a global error handler which can log it and/or send out some kind of error notification.
I discovered the reason yesterday. In short it was because when I copied my files from my computer into my dev-test environment, I missed a file, which ironically caused it to work, rather than not. So in the end it would have functioned the same in both environments.

ASP.Net links won't disable if done during postback

I'm still fairly new to ASP.Net, so forgive me if this is a stupid question.
On page load I'm displaying a progress meter after which I do a post back in order to handle the actual loading of the page. During the post back, based on certain criteria I'm disabling certain links on the page. However, the links won't disable. I noticed that if I force the links to disable the first time in (through debug) that the links disable just fine. However, I don't have the data I need at that time in order to make the decision to disable.
Code Behind
If (Not IsCallback) Then
pnlLoading.Visible = True
pnlQuote1.Visible = False
Else
pnlLoading.Visible = False
pnlQuote1.Visible = True
<Load data from DB and web service>
<Build page>
If (<Some Criteria>) Then
somelink.Disable = True
End If
End If
JavaScript
if (document.getElementById('pnlQuote1') === null) {
ob_post.post(null, 'PerformRating', ratingResult);
}
ob_post.post is an obout js function that does a normal postback and then follows up with a call to the server method named by the second param. then followed by the call to a JavaScript method named by the third param. The first parameter is the page to post back to. A value of null posts back to the current page.
The post back is working fine. All methods are called in the correct order. The code that gives me trouble is under the code behind in bold. (somelink.disabled = True does not actually disable the link) Again, if I debug and force the disabling of the link to happen the first time in, it disables. Does anyone know what I might do to get around this?
Thanks,
GRB
Your code example is using the IsCallBack check, while the question text talks about the IsPostback Check. I'd verify that you're using Page.IsPostBack in your code to turn off the links.

Resources