Happy New Year!
Very brief news: We’ve been working hard on our software products for the last few months. We’re building a large line of business application for a service franchise and a few stores opened with our software in Ireland, Scotland, Mexico, and, more recently, China. We’ve also contributed some work to the jUCMNav open source project, which focuses on visually representing software requirements.
Today, we encountered a weird little bug in Internet Explorer and we thought it might be good to describe the workaround which we found thanks to StackOverflow.
We're using a control that uses ASP.NET callbacks (not postbacks) in our page. However, in certain circumstances, the control stops working.
Problem: ASP.NET callbacks are not fired in Internet Explorer
- The control works fine in FireFox, Google Chrome, etc.
- The control works fine if we do not use ASP.NET AJAX History. As soon as we call the following code, the callbacks stop working in IE (6, 7, and 8)
- I did some server side debugging to figure out that RaiseCallbackEvent was not fired in IE, but was fired for others.
- I have debugged using Fiddler and observed that it was not querying the appropriate URL. The server returns an invalid request error.
Root Cause : IE thinks the anchor (hash tag) is part of the filename.
Other browsers send the HTTP POST to: test.aspx but Internet Explorer is sending it to: test.aspx%23&&h=12
This is because the URL in the browser's bar is test.aspx#&&h=12, because of our AJAX History Control. For some reason, it URL Encodes the hash tag, but not the rest, and appends it to the aspx filename. Other browsers don’t exhibit this behaviour.
Technique 1: Add a query string parameter
I found that if the browser was at a certain URL such as test.aspx?test=ing that the control worked fine. This is because appending the AJAX history to this URL makes test.aspx?test=ing%23&&h=12. This implies that we’re sending an invalid test query string of (ing%23&&h=12), but since we’re not using this query string parameter, it does not really matter. However, this does give you an ugly address.
Technique 2: Change the form’s action parameter
Gabriel McAdams lead me in this direction on StackOverflow.
Reading the contents on WebForm_DoCallback, I didn't see anything that set the URL of the server call. This means that it is either getting it from the form action or sending it to the current page. Try setting the form's action attribute.
Indeed, this is the solution we were looking for. ASP.NET has a single server-side FORM element named aspnetForm (auto-generated). If you remove the hash-tag from the form’s action parameter, the control works in all browsers. I assumed that the following code in the right spot would fix the issue, but it did not since ASP.NET’s action element is auto-generated. Any changes made to action don’t seem to do anything. (By default, Action is empty, forcing the browser to decide what URL to use for the current page, which must be the root problem here.)
this.Page.Form.Action = HttpContext.Current.Request.Url.PathAndQuery;
<div onmousedown="$('#aspnetForm').attr('action', '<%= HttpContext.Current.Request.Url.PathAndQuery %>')">
<!-- my control is in here - I could have executed the above code after every postback, but was sufficient for my needs -->
I’m executing the code when the mouse button is pushed here (sufficient for my needs, and executed before the click event which caused my problems). A cleaner solution would have you output this automatically when necessary. Note that I had tried changing window.location.hash to an empty string before the callback, but this caused the page to scroll, left the hash character in the URL, and broke my AJAX history.