3

Background
I have an ASP.net UserControl that is a simple user input form. It uses an UpdatePanel and UpdaetProgress to display a "working" gif after they click submit. We have gotten reports that the submit button sometimes doesn't do anything in FireFox, IE 8, and Safari. When looking into that, I couldn't reproduce any problems in IE, but found that in FireFox, the submit button got the following script error which was preventing the postback:

Error: Sys.WebForms.PageRequestManagerServerErrorException: 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.
Source File: http://localhost:1127/ScriptResource.axd?d=ZYU-uPMJ_AcQgBrmkW_WO13JlNZSAb9cMptxJsQIH1LnA8NC31pa7PAk8l5lYCB8LDDwft7xwh7Z107MKgt7KHHBeQaeEncnAFKLJ04CaHgelsuOOv072-1ZBvMW7N_x0&t=3693a5e0
Line: 1111

Problem
To figure out what was causing the error, I gradually whittled down my code until I had almost nothing left. What I found was that when I select from a DropDownList in an UpdatePanel, the button gets this error (in FireFox only). If I remove the DropDownList, don't make a selection, or remove the UpdatePanel, the submit button posts back correctly (any 1 of those).

Example
Create an ASP.net 3.5 project and place the code below in an aspx page. Set a break point in your Page_Load or OnClick event handler in the code behind. Run it, make a selection from the DropDownList and then ClickSubmit. Notice the breakpoints are not hit.

<form id="form1" runat="server">
    <div>
        <asp:ScriptManager runat="server">
        </asp:ScriptManager>
        <div id="Div1" class="form-layout membership payment">
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" RenderMode="Inline">
                <contenttemplate>
                    <table cellpadding="0" cellspacing="0" border="0" class="form_table payment">
                        <tr>
                            <th align="right" valign="top">
                                State <span class="reqd">*</span>
                            </th>
                            <td>

                                <asp:DropDownList Width="75px" ID="ddlState" CssClass="txt" runat="server" AutoPostBack="false">
                                    <asp:ListItem Value="" Text="--Select--" />
                                    <asp:ListItem>AB
                                    </asp:ListItem>
                                    <asp:ListItem>AL
                                    </asp:ListItem>
                                </asp:DropDownList>
                            </td>
                        </tr>
                    </table>
                    <div class="clear-left pad-bottom">
                    </div>
                    <asp:Label ID="lblCreditCardError" CssClass="creditCardError" runat="server">
                    </asp:Label>
                    <table cellpadding="0" cellspacing="0" border="0" class="form_table">
                        <tr>
                            <th align="right" valign="top">
                            </th>
                            <td>
                                <asp:HiddenField ID="HFSubmitForm" runat="server" Value="0" />
                                <asp:Button ID="btnTest" runat="server" OnClick="btnSubmitCC_Click" />
                            </td>
                        </tr>
                    </table>
                </contenttemplate>
            </asp:UpdatePanel>
        </div>
    </div>
</form>

I don't think using markup should matter anyway, but I tried adding the items to the DropDownList using binding in an if(!IsPostBack) block in the Page_Load method, but it didn't change anything.

xr280xr
  • 12,621
  • 7
  • 81
  • 125

3 Answers3

3

I'm not sure if this causes your issue, but try to format the DropDownList-Items correctly:

<asp:DropDownList Width="75px" ID="ddlState" CssClass="txt" runat="server" AutoPostBack="false">
     <asp:ListItem Text="--Select--"></asp:ListItem>
     <asp:ListItem Text="AB"></asp:ListItem>
     <asp:ListItem Text="AL"></asp:ListItem>
</asp:DropDownList>
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Wow...that fixes it. Now I need to know why. Remember it's only FireFox that the original syntax causes the error for. I tried moving the states into a generic list and binding to that again, and now it works too which I thought didn't work before, but I must have had another DropDownList on my form still. – xr280xr Sep 27 '11 at 14:32
  • I should add, this has been in production for about 2 years and we just now started getting complaints so it seems likely to be related to recent FireFox updates. – xr280xr Sep 27 '11 at 14:52
  • @xr280xr: Have you seen what's being rendered as HTML? I think the line breaks are confusing and therefore removed on an async postback from Toolkit(i assume). But now ASP.NET thinks that the items have changed during postback. This causes your security warning "Invalid postback or callback argument" – Tim Schmelter Sep 27 '11 at 16:26
  • You're right, I had missed that. See my reply with details in the answer below. Thanks for your help! – xr280xr Sep 28 '11 at 14:49
0

First off, you are missing this under your UpdatePanel:

<Triggers>
    <asp:AsyncPostBackTrigger ControlID="btnTest" />
</Triggers>

Second... either bind the list options in code-behind, turn off event validation for this page, or call RegisterForEventValidtion() for each of your options, I believe. I'm a little sketchy on this last one since I've never really used it. I was able to get your code working by simply adding the AsyncPostBackTrigger and then binding the DDL in code-behind.

Finally, it's possible that you are simply missing these unhandled exceptions while debugging because you are expecting something from the browser... but really it should appear to the browser that nothing has happened. Pull up EventViewer to see unhandled ASP.NET exceptions. The exception is stopping execution before you get the event handler.

Bryan
  • 8,748
  • 7
  • 41
  • 62
  • Maybe useful: http://stackoverflow.com/questions/5942244/how-should-registerforeventvalidation-be-used-correctly – Bryan Sep 26 '11 at 23:04
  • 1
    Thanks Bryan. The UpdatePanel defaults ChildrenAsTriggers to true so explicity declaring the button (a child) as a trigger is not necessary. A good indication of that is if I don't make a selection from the drop down, it does postback. I tried this solution yesterday, and again today after reading your post but it doesn't fix it for me. Turning off event validation bypasses the error, but doesn't really solve anything. I want to determine why it thinks its invalid when coming from firefox. Unlike the example you linked to, I'm not (knowingly) modifying any values on the client side to cause it – xr280xr Sep 27 '11 at 14:36
  • 1
    Ah... I was thinking it would trigger a regular PostBack if you don't explicitly set it as an AsyncPostBackTrigger. My mistake. If there is really a difference between behavior in Firefox and IE, you should be able to see that by comparing raw HTTP requests in Fiddler. – Bryan Sep 27 '11 at 21:36
0

@Tim Schmelter- Ahhh that explains it. (Replying in an answer so I can show code and make sure your answer is clear) Here's what ASP.NET sends to the browser:

<SELECT style="WIDTH: 75px" id=ddlState class=txt name=ddlState> 
    <OPTION selected value="">--Select--</OPTION> 
    <OPTION value="AB&#13;&#10;                                    ">AB</OPTION> 
    <OPTION value="AL&#13;&#10;                                    ">AL</OPTION>
</SELECT>

&#l3;&#l0 is /r/n. In IE, this whole value displayed above is included in the HTML, but in FireFox it's reduced down to a single space (e.g. "AB "). When it's passed back to the server it sees the selected option's value is not one that was originally included. I had compared the HTML sent to what was in FireFox but I looked at the above HTML in Visual Studio's XML Visualizer which also removed them so I didn't notice the difference.

xr280xr
  • 12,621
  • 7
  • 81
  • 125