ASP.NET Ajax AddHistoryPoint Bug

 In .NET Framework SP1 there was a great feature added that allows history points to be added for Javascript changes. This means, you can use the browswer back/forward buttons with Javascript changes on the page.

When released, I went to implement it, and quickly found there is a  bug that causes this feature to not work at all in IE.

Problem:

To use this feature on the client, you enable it by setting EnableHistory="true" on the ScriptManager. What this does is renders "Sys.Application._enableHistoryInScriptManager();" right before it renders "Sys.Application.initialize();" on the page. To create a history point, you call "Sys.Application.addHistoryPoint(state, title);". You then subscribe to an event "Sys.Application.add_navigate". This event should fire every time "addHistoryPoint is called, and every time the page navigation is clicked within the current history.

The problem is, with IE there is an iframe tag rendered that has this code in it "parent.Sys.Application._onIFrameLoad();". If the iframe loads before the parent page has rendered and the "Sys.Application._enableHistoryInScriptManager();" method has been called, the navigate event never gets called, and you can't recreate the state on your page.

Solution:

I submitted a support incident to Microsoft to get this issue resolved. The person helping me confirmed it was a bug and passed it on to the ASP.NET team to check it's validity. I didn't hear anything back for several weeks. This past week I was at PDC and decided to ask Bertrand LeRoy about it, since he's the creator of this feature. He was able to recreate the problem, and sent an email off to get a bug issued.

Today I get a call from MS Support and was told that this issue was fixed in IE8, but not in IE7 or IE6 and they expect their customers to move to IE8 so they're not going to worry about IE6/7.

This is really sad considering IE8 hasn't even been released yet, and IE6/7 are still supported. This makes it pretty much impossible for me to implement this feature. I can't expect my users to upgrade to a browser that is still in beta. According to wschools, as of October 2008, IE6 still holds 20.2% of the market and IE7 holds 26.9%.

To get this problem to occur, there needs to be enough stuff on the page going on for the iframe to load before the bottom of the parent page loads. The page where I'm seeing this issue is around 400k, give or take 100k. This is a fairly large page, but there is a lot of content and javascript going on withing the page, and there isn't much room for trimming. An easy way recreate it is to just add a whole bunch of garbage text to the page. With this method the page ends up being around 7-8MB before you see the issue occur. Again, I see it at 400k.

Sample:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="HistoryNavigationProblem._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager runat="server" ID="scriptManager" EnableHistory="true"></asp:ScriptManager>
        
        <script type="text/javascript">
            Sys.Application.add_init(pageInit);

            function pageInit(sender, e)
            {
                Sys.Application.add_navigate(navigateHandler);
                $addHandler($get("<%= this.button.ClientID %>"), "click", buttonClickHandler);
            }

            function navigateHandler(sender, e)
            {
                var label = $get("<%= this.label.ClientID %>");
                label.innerHTML = e.get_state().text;
            }

            function buttonClickHandler(event)
            {
                event.stopPropagation();
                event.preventDefault();
                
                var label = $get("<%= this.label.ClientID %>");
                var text = $get("<%= this.text.ClientID %>");

                Sys.Application.addHistoryPoint({ text: text.value });
                
                text.value = "";
            }
        </script>
        
        <asp:Panel runat="server" DefaultButton="button">
            <asp:Label runat="server" ID="label"></asp:Label>
            <asp:TextBox runat="server" ID="text"></asp:TextBox>
            <asp:Button runat="server" ID="button" Text="Add" />
        </asp:Panel>
        
        <asp:Label runat="server" ID="lblJunk"></asp:Label>
        
    </form>
</body>
</html>

[Edit]

Bertrand LeRoy has confirmed that this bug is not closed, and they're planning on releasing a fix for IE6/7 with the next .NET release. MS Support was wrong.

Thanks Bertrand!

9 Comments

  • Hey Josh. Not sure why they told you we weren't going to bother fixing this... IE 6 and 7 are still supported browsers for Ajax. We are going to fix this in 4.0. In the meantime, I think that calling _enableHistoryInScriptManager and _ensureHistory right after where the iframe gets rendered should work around the problem.

  • Bertrand, that is so great to hear. I thought that answer was unlike the ASP.NET team, but that is what MS Support told me when they closed the issue. Also, when I talked to you at PDC, you seemed to think the issue would be pretty easy to solve, and it would be fixed in a future release, so the resolution from support seemed odd.

    The official closing statement in an email I got last night is "After having working with the product team we identified that the issue that you are facing is due to a bug in the AJAX framework. This has been fixed for IE 8 and going forward however the issue continues to persist for IE 6 and IE 7.", which doesn't explicitly say that it's not being fixed in IE6/7. I asked a couple times about it to make it 100% clear to me that the issue was not going to be fixed in 6/7. I guess he was mistaken.

    I tried putting _enableHistoryInScriptManager and _ensureHistory right after the script manager tag, which is the first thing in the page, but it doesn't work. I'll send you my sample code.

    Thanks for the comment Bertrand.

  • Yes, please do that. Please also send me the number of the bug that was closed. I'm suspecting there's been a misunderstanding or confusion about the actual problem. We have closed quite a few bugs about history problems on IE6 that had to do with platform limitations that are impossible or not worth working around. The problem that you describe is clearly different and something that we know how to fix.

  • I sent you a sample app, and now the bug number. Let me know if you're not receiving my emails. My emails showed up in the spam folder for the support person.

  • Got it. Definitely some confusion from support about the issue. I sent you the correct bug number, and that one is clearly still open and being looked at.

  • Was there an update to this issue? I'm hitting a similar problem, and was going to load a clientside method to parse the values and override my ascx set values.

  • Any News Guys?? Firefox works ok????

  • I've just tested in ie8 and it seems to work ok, but when you view the history list while viewing the new page that you've navigated too, the list is missing entries until you click back. Maybe framework 4 beta will fix that??

  • obPcnt Looking forward to reading more. Great article post.Thanks Again. Cool.

Comments have been disabled for this content.