Retaining read only control values on postback

Since .NET 2.0, the postback has changed in ASP.NET. In .NET 1.1 when a readonly server side control is made writable by client side JavaScript, the values are retained on the postback. For instance, in the following page we have a readonly text box, TextBox1, with one client side button, Enable, and one server side button, Button1. On the click of Enable button, the TextBox1 will become enabled and user will be able to enter the text. On the click of Button1 button, the form will be submitted to the server and a postback would occur. In the event handler of Button1 we can inspect the value of TextBox1 to see what value it has.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script  type="text/javascript">
        function WriteText() {
            document.getElementById('TextBox1').removeAttribute('readonly');
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <input id="Enable" type="button" value="Enable" onclick="WriteText()" />
        <asp:Button ID="Button1" runat="server" Text="Submit" onclick="Button1_Click" />
    </form>
</body>
</html> 

When the order of the events is: Enable button click, enter text in the TextBox1, click Button1, the form would get submitted to the server with the entered value in the TextBox1. This is what we would expect and it does work this way in .NET 1.1. However, since .NET 2.0 it has been a different story. On the postback, the values entered in the TextBox1 would get lost. Luckily, there is a simple solution.
The workaround involves removing readonly static attribute and adding it in the behind Page_Load method:

using System;
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        TextBox1.Attributes.Add("readonly", "readonly");
    }
} 

Conclusion
Mixing client side script with server side controls may create an unpredictable result. Its behavior is inconsistent across .NET framework versions. Therefore it is imperative to test the code thoroughly without any assumptions.