ASP.Net RadioButton loses ViewState

asp.netpostbackradio-buttonviewstate

I'm having trouble with a simple radio set of two radio buttons (I don't want to use a RadioButtonList [RBL] because RBL doesn't allow child controls, and in my case, if you select one option, I want to enable a textbox next to the button; yes you could hack this with jQuery to move the textbox, but that's dirty!). I would check one, submit the form (either explicitly or through AutoPostBack), and the CheckedChanged event would never fire. When the page was reloaded, both buttons would be unchecked, regardless of their initial state on non-postback load or the state before form submission.

I took out the checkbox and stripped this down to the simplest example I could come up with. I tossed EnableViewState=true all over the place just in case it was being disabled somewhere I couldn't find.

<form id="form1" runat="server" enableviewstate="true">
    <div>
        <asp:RadioButton ID="foo" Text="foo" runat="server" AutoPostBack="true" OnCheckedChanged="rbChanged" Checked="true" GroupName="foobar" EnableViewState="true" />
        <asp:RadioButton ID="bar" Text="bar" runat="server" AutoPostBack="true" GroupName="foobar"
            OnCheckedChanged="rbChanged" Checked="false" EnableViewState="true" />
        <asp:Label runat="server" ID="resultLbl" />
    </div>
</form>

protected void rbChanged(object sender, EventArgs e)
{
    if (foo.Checked) resultLbl.Text = "foo is checked";
    else if (bar.Checked) resultLbl.Text = "bar is checked";
    else resultLbl.Text = "neither is checked";
}

Best Answer

It turns out this was because we had a custom adapter rendering the HTML for a radiobutton (or to be precise, for all System.Web.UI.WebControls.CheckBox es). Our motivation for this was because .NET will put a disabled="disabled" attribute on the LABEL and the input, which is bad HTML, and worse, is actually interpreted to mean something by IE! (Check it out for yourselves -- write up an HTML page with a label disabled="disabled" and test in FF and IE.)

We used Reflector to see what step we were mixing up vs what the real adapter did, and found that the Name attribute was being set incorrectly. Although it set all the RBs in a given group to the same Name, it was not the same Name attribute in our limited new-solution test case as it was in our custom-adapter test case. When we looked at how to generate that safely, we found that our postbacks suddenly worked!

If we get permission from the boss, we'll contribute our adapter to CSSFriendly in case anyone else has use for this sort of thing.

Related Topic