In the website I'm working on, there is a bug I'm unable to figure out.
The bug is the following.
I have two different pages (with different functionality/controls). Both of them include the same page header that include a logout button.
<form id="Form1" method="post" runat="server">
<uc1:pageheader id="PageHeader1" title="XXXXX" runat="server"></uc1:pageheader>
<!-- page content goes here -->
</form>
The button is the following (located in pageHeader.ascx)
<INPUT type="button" value="Log out" id="btnLogout" name="btnLogout" runat="server" onserverclick="btnLogout_ServerClick">
With a server side function btnLogout_ServerClick that handle the disconnection.
In one of the page, the button is doing its role just fine.
In the other the btnLogout_ServerClick function is never reached.
I tried to put a breakpoint in the page_Load function of both pages. They both start with a first passage with the IsPostBack value set to True but after going through the loading of every control on the page, the first one end up in the log out function, whereas the other starts a new page_Load cycle with IsPostBack set to False.
There is no trace of error/exception on what could cause this behavior, if anyone could give a hand, either in giving a solution or providing a way to find the problem, that would be welcome.
And I know that I could try to remove every control and add one at a time to see if they prevent the button from working, but both pages have numerous control and it'd be nice if I could avoid that.
Use browser tools (IE dev tools, Firebug etc) to see if the posted data is the same in both cases. If there are any redirects check if other code is not doing redirect before the event is raised.
First thing I would check is the event handler for the button. Are you sure it is correctly registered ?
Possibly related to user control event handler lost on postback
Related
Synopsis:
I have a login page has two bootstrap modals, one for registering a new account and one for logging into an existing account. Intermittently I'm seeing an issue where trying to log in results in the method for the registering submit button being fired instead of the method for the login button (the one clicked).
Details:
I'm going to describe some of the layout and post code where necessary. I'm trying to avoid posting a ton of code since I'm not exactly sure where the issue lies. This page is a childpage of the site.master, has multiple .css and .js files associated with the theme and the site functionality.
'signup-modal' modal includes a few input fields and then the submit button 'Button1', whose onclick parameter fires the server-side 'RegisterUser' method in the code behind file (C#).
'login-modal' modal includes inputs for username/password, a remember me checkbox, a login with facebook button and the submit button, whose onclick parameter fires the server-side 'ValidateUser' method in the code behind file (C#).
Each modal is surrounded by an UpdatePanel.
When a user has the login modal open and fills valid information then clicks the login button it will typically operate as expected, firing the 'ValidateUser' method, checking the information with the database and authenticating/redirecting the user to the content page. However, occasionally when clicking the login button the 'RegisterUser' method fires instead and returns an error I coded for when the DB tells it that the username entered already exists.
Unfortunately I can't seem to consistently recreate this error, but it does seem to be related to the authentication. I'm using FormsAuthentication to set authentication cookies for the user once they've been validated by the user database. I've noticed that when this error happens, if the cache is cleared, then you are able to login successfully.
What I don't understand is why anything in Session authentication should cause the wrong method to fire onclick. Especially since when it fires the button control it's associated with is hidden and should be inaccessible. The best I can figure is that somehow all onclick methods are being fired and because the 'RegisterUser' one is first in the html, that is the one being executed?
What I've Tried:
I had read a couple posts where people would see this type of behavior as a result of blank labels:
ASP.NET: Wrong event is fired when I click a LinkButton
I don't see anything like that in my code, however I did have a class="" call out in an ASP:Button control that was generating a warning about class="" not being a valid parameter. I tried removing that but didn't see any change in behavior.
I have included on both forms (in each modal) required field parameters, which I remove/add VIA javascript when the modal is hidden or shown. The reason I remove it is that an error is thrown if a required field is hidden due to the browser trying to find the control to validate and not seeing it. Since the 'RegisterUser' method fires without the browser trying to authenticate the associate fields I can surmise that the button is actually hidden (with the required parameters removed) and not just off screen or something.
I have tried without success to determine why this only happens intermittently. It doesn't seem to be due to the number of authenticated sessions under one username. I have logged into over 5 sessions on different computers/browsers without getting the error and had it happen on the first login attempt for a user.
Also, I can confirm that I've seen this error across Chrome, IE, Edge and Firefox, again intermittent on all.
I've double checked that the 'RegisterUser' method isn't being called anywhere else besides the onclick function of the register button.
I haven't been able to find any other posts similar to this, so I'm turning to you in desperation.
The Question:
So if you've made it through all that, here's the real question; What would cause the wrong OnClick method to fire? Am I correct in my educated guess that it has something to do with the Session authentication?
I would also appreciate some advice on where to take my troubleshooting from this point. I can post code snippets as necessary, I'm just not sure what would be relevant and given the volume of code I didn't want to just post it all.
Code Snippets:
The buttons:
Register Button:
<asp:Button ID="Button1" runat="server" onclick="RegisterUser" Text="Create Account" CssClass="btn btn w-lg btn-rounded btn-lg btn-custom waves-effect waves-light" />
Login Button:
<asp:Button ID="btnSubmit" runat="server" onclick="ValidateUser" Text="Sign In" CssClass="btn btn w-lg btn-rounded btn-lg btn-custom waves-effect waves-light" />
Outline of RegisterUser Method
protected void RegisterUser(object sender, EventArgs e)
{
/* Code that registers user with database if username doesn't exists */
}
Outline of ValidateUser Method
protected void ValidateUser(object sender, EventArgs e)
{
/* Code that validates user with the database and authenticates if valid. */
}
Please let me know if there is any more information that would be helpful to include and I'll update the question.
Thank you very much in advance.
UPDATE
I̶'̶v̶e̶ ̶f̶o̶u̶n̶d̶ ̶t̶h̶a̶t̶ ̶I̶'̶m̶ ̶a̶b̶l̶e̶ ̶t̶o̶ ̶r̶e̶p̶r̶o̶d̶u̶c̶e̶ ̶t̶h̶i̶s̶ ̶e̶r̶r̶o̶r̶ ̶1̶0̶0̶%̶ ̶w̶h̶e̶n̶ ̶r̶u̶n̶n̶i̶n̶g̶ ̶o̶n̶ ̶l̶o̶c̶a̶l̶h̶o̶s̶t̶ ̶a̶s̶ ̶o̶p̶p̶o̶s̶e̶d̶ ̶t̶o̶ ̶t̶h̶e̶ ̶d̶e̶v̶e̶l̶o̶p̶m̶e̶n̶t̶ ̶s̶e̶r̶v̶e̶r̶.̶
(Turns out this isn't the case)
Here's another odd behavior I seem to have stumbled upon. If I type out the user name and password, the RegisterUser method fires. However, if the username and password are filled by a password manager, the ValidateUser method is fired (Correct action).
Check your button declaration in your .aspx source.
If you have a 'runat=server' and onclick="RegisterUser", and you have an event handler in your code-behind, it will cause the event to be fired twice.
If so try to change this
<asp:Button ID="Button1" runat="server" onclick="RegisterUser"
Text="Create Account" CssClass="btn btn w-lg btn-rounded btn-lg btn-
custom waves-effect waves-light" />
To this
<asp:Button ID="Button1" runat="server" Text="Create Account"
CssClass="btn btn w-lg btn-rounded btn-lg btn-custom waves-effect
waves-light" />
Some others say that adding type="submit" has helped them out.
Another case might be that your event handler in the server side might be causing the event to be triggered twice.
For instance if you have:
Protected Sub RegisterUser_OnClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles RegisterUser_Click
'Do Something
End Sub
The Handles RegisterUser_Click might cause the event to be fired twice.
Nice explanation btw. Hope the best. Lets us know what was the issue. Best of luck.
I've updated my .Net web application to use Framework 4.5, after the update, all the input buttons (not asp:Buttons), have stopped firing the onclick javascript code, this is only happening on those buttons that are inside a user control (.ascx).
Just for the record, user controls are neither being loaded dinamically nor inside update panels.
My buttons look like this
<input id="cb" onClick="myfunc()" type="button" value="Close" />
My user controls are included to the page as follows
<cc:actionbar id="theActionBar" runat="server"></cc:actionbar>
and the javascript function, which is also included within the user control, is
function myfunc() {
if (confirm("Before closing, please make sure you saved any changes.\nAre you sure you want to close?") == true) {
__doPostBack('theActionBar:theClose', '');
}
}
this works just fine on Framework 3.5 and previous versions.
any idea why is this happening??? or how can I solve this?? I have tried several suggestions I've found over the internet and nothing seems to work.
Thanks in advance.
.
I can't see an obvious reason, but have you considered simplifying your approach to avoid the custom javascript and hard-coded postback event reference? You can get exactly the same behaviour with an ASP.NET button's OnClientClick property:
<asp:Button runat="server" ID="btnClose" Text="Close" OnClick="btnClose_Click" OnClientClick="return confirm('Before closing, please make sure you saved any changes.\nAre you sure you want to close?')" />
Returning false from the OnClientClick code or function prevents the postback.
Switching to this approach may be preferable and may even solve your issue if it's something to do with the postback event reference.
My Question
I managed to answer myself, however the same set of functionality has another problem. For some reason the first postback of the save event of the posted file hits the Ol' Object not set to an instance of an object error, but on the second attempt of uploading a file and firing my save event (converts to byte[] an stored as SQL Server BLOB) it does everything is supposed to do.
Same problem here
There is a good suggestion of using the AJAX AsyncUpload control however I am a firm believer of removing the cause and not treating the problem. I will continue down this route to best my understanding of asp.net etc.
Would there be a wizrd amongst you that could help me identify why I get "object ref not set to inst of obj" error on first postback but on second it works fine. Content page has a master page which wraps content page in an update panel. Not my decision to do this. There is also an update panel with postback triggers targeting my save event.
What are your thoughts people?
The problem (as seen here http://forums.asp.net/t/1060363.aspx) seems to be when you use the visibility property on the surrounding panel (as it seems you are from the linked question).
The suggested workaround is to use CSS visibility instead so use this to make it invisible -
<asp:Panel ID="pnlUpload" runat="server" class="workerDetailsPanelLeft" style="display:none">
The explanation for this from the thread is
If your container is set to invisible, the upload control is not actually rendered as HTML, causing the form's enctype not to be set to enctype="multipart/form-data", causing the file upload control not to post the selected file back to the server. The workaround is either to make sure the FileUpload control is rendered to HTML (by setting its style to display:none in stead of Visible=false), or by manually setting the enctype
So another workaround would be to alter your form tag to this
<form id="form1" enctype="multipart/form-data" runat="server">
I think either one of those should solve your problem.
You could do the same thing via code on Page_Load event.. Enter this code and it will solve the issue.
Page.Form.Attributes.Add("enctype", "multipart/form-data");
I have an asp button that produces this html:
<input type="submit" name="ctl00$m$g_a2ba5666_c8e9_4bd7_a44a_f9407dbe2199$ctl00$btnAddWebPart" value="Add Report" id="ctl00_m_g_a2ba5666_c8e9_4bd7_a44a_f9407dbe2199_ctl00_btnAddWebPart" />
When the button is submitted and the page_load method is hit, I am trying to do this:
String target = Page.Request.Params.Get("__EVENTTARGET");
but, for some reason 'target' is empty. I checked to see if __EVENTTARGET is getting populated and it is an empty string. Any ideas as to why this is happening? It is something really silly.
Thanks.
Wrap this button up in an ajaxtoolkit update panel. that way you can update the various page components (add / remove your web parts) within an async call.
This means that the page is partially rendered instead of it being the result of a full postback.
I agree with Josh on this ... handling the event in this way is ugly and against the intended purpose of this part of asp.net from microsoft.
partial postbacks dont result in that ugly flicker effect so this should produce the result you want and not effect the rest of the page.
I have a menu usercontrol called LeftMenu that has a bulletedlist of linkitems. It's on the ascx page as such:
<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList>
I databind the list in the page_load under if(!isPostBack)
I'm having an issue on a page that loads the control. When the page first loads, the event handler fires. However, when the page posts back it no longer fires and in IE8, when I'm debugging, I get "Microsoft JScript runtime error: Object expected" in Visual Studio pointing at "__doPostBack('LeftMenu$PublisherList','0')." In FF I don't get the error, but nothing happens. I'm not loading the control dynamically, it's loaded on the aspx page using:
<%# Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %>
<Standards:LeftMenu ID="LeftMenu" runat="server"/>
Any ideas of where I'm losing the event handler?
I just realized this is happening on another user control I have as well. A text box and a button and I'm using the default button to make sure pressing the enter key uses that button. .Net converts that in the html to:
<div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')">
so as soon as i enter a key in the box I get a javascript error at the line saying "object expected." It seems like the two issues are related.
Edit Again: I think I need to clarify. It's not that I'm clicking on the menu item and it can't find the selected item on postback. I have this search page with the left navigation on it and then the main content of the page is something that causes a postback. Everything is fine with this postback. Once that page has been posted back, now if I click on the bulleted list in the left navigation I get a javascript error and it fails. The page_init for the LeftMenu control is never called.
It sounds like you might be losing the click because you are not DataBinding the list on PostBack. Therefore, the post back is trying to refer to a control (a specific bulleted list item) that does not exist.
You should try binding the list again on PostBack just to see if that fixes your issue. BUT, what should REALLY happen is that the LeftMenu and the BulletedList should store their information into ViewState so that you can ensure that the data that was shown to the user on their initial page load is the same data that the PostBack is processing and working with.
If you have EnableViewState=true for your UserControl and all controls within it, everything should work fine. With ViewState enabled, ASP will reinflate your controls from ViewState after Init has fired. This means that the postback event arg (which points to an index in your control list) will still find the control in that list position. Otherwise the list is empty on postback.
However, ViewState is the work of the devil and was designed simply to foster the illusion that you are working in a stateful environment. It is okay to use it for small amounts of data but typically not advisable for templated controls like repeaters and lists because you have no idea how much data is going to be created in ViewState.
If you are dealing with static, or relatively static data, store it in the application cache and rebind your lists in Page.Init every time (note that it has to be in Init because post-init is when ASP rebinds from ViewState; if you get in there first, your data will be used instead).
If you are dealing with volatile data, you have a problem because the data you rebind must be exactly the same as the original page request, otherwise the postback events will be firing against the wrong rows. In that case you need to either store your initial data in Session or you simply store the list of rows ids (in a hidden variable or Session) and you recreate the data to bind against from the ids each time.
An even better solution is to not use postback events at all. Try to turn all your events into GETs that have an ID on the query string. You can still create the list using binding the first time through the page (as you are currently doing), and you can even GET the same page with a new ID.
If you need to keep state on the same page but need to respond to the user changing a radio button selection (or something else), think about using Ajax calls to update the screen. You also do that with an ID that you pass to the Ajax call.
In general, the more you move from using stateful ASP, the lighter and more responsive your pages will become. You will also be in a better position to move to stateless MVC if necessary. You will also save lots of time lost to debugging obscure problems because ViewState is not available when you need it to be.
The best analysis of ViewState I've read is in the link below. If you fully understand how it works, you can continue to use it without necessarily incurring the costs.
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx
It's possible that this might be javascript related, and that a script that is loading earlier in the page is throwing an error and causing the page to not be loaded properly.
Are your usercontrols loading any javascript onto the page? Can you check for javascript errors on the initial load of the page?
I moved the code into an existing project we have and for some strange reason, I stopped getting the javascript errors and instead got:
"Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
I haven't quite figured out where I'm supposed to put the register event validation with a user control, but in the mean time I just set enableeventvalidation=false and it seems to work now.
It looks like the doPostBack function is missing since its arguments are literals so they couldn't be the cause. Is that one of your own functions or did you mean to call the ASP __doPostBack function?
Have a look at the Firefox error console or allow script debugging in IE and see exactly what object can't be found. Even better, download Firebug and debug it.
I had a similar issue. It turned out that Akamai was modifying the user-agent string because an setting was being applied that was not needed.
This meant that some .NET controls did not render __doPostBack code properly. This issue has been blogged here.