ASP.NET 2.0 TextBox Ready Only losing client side changes, values across postback? Harish

Well, this has been under discussion for sometime and I knew this was a known issue although it was a design change in ASP.NET 2.0.

I am talking about the TextBox which has the Read Only property assigned true not retaining the values or client side changes getting ignored across postbacks.  There are certain blogs / articles which talk about it but for the benefit of those who get stuck with this, I am giving herebelow the steps to reproduce and the resolution for the same.

ASP.NET 2.0 had a design change by which a an <asp:TextBox> control if marked with its ReadOnly property as true, would ignore client side changes and would lose the same across postback.  So if you tried modifying the text box value or add a value to the text box using Javascript you wouldnt be able to retireve the value in the code behind or simply the value will be lost across postback.

Try doing this

Declare a TextBox

<asp:TextBox ID=”TextBox1″ runat=”server” Text=”Sample Text” ReadOnly=”true” />

Add the following Button

<asp:Button ID=”Button1″ runat=”Server” Text=”Submit” OnClick=”Button1_Click”  />

The purpose of the above button is to invoke a code behind method, the click event where we can do a Response.Write of the TextBox value.

So, in the code behind, add the following method

    protected void Button1_Click(object sender, EventArgs e)
    {
              Response.Write(TextBox1.Text);
    }

then add the following button

<input type=”Button” name=”Button2″ onclick=”changevalue()” />

The purpose of the input type button is to execute a client side javascript.

The client side script is as follows:-

 <script language=”javascript”>
        function changevalue()
        {
        this.form1.TextBox1.value = “Modified Sample Text”;
       
        }
   
    </script>

Place the above script before the </head> tag in your HTML Source.

Now, if you click on the input type button you will see that the TextBox value changes to “Modified Sample Text“. 

However, when you click on the button “Submit” which is an <asp:Button>, a server control, you will see that the text that it writes to the browser is again “Sample Text“.  You will also see that the TextBox has the value reset to “Sample Text”.

This behaviour is new in ASP.NET 2.0 and if you are migrating your ASP.NET 1.x applications you may find this a little annoying / worrying since the values aren’t retained.

This is independent of whether you set the EnableViewState property for the TextBox to true or false.  In fact the EnableViewState property for a TextBox doesnt make a difference since the values in a TextBox are maintained and retrieved from the Form’s Collection and not from the ViewState.

However, there is a work around for the same.  Instead of setting the “Read Only=true” property in the design you can enable the ReadOnly property of the TextBox through the Attributes collection in the code behind.  To do that, remove the ReadOnly property from the TextBox declaration above.  Then, in the code behind file, within the Page_Load add the following line of code:-

TextBox1.Attributes.Add(“readonly”, “readonly”);

Now you will notice that when you run the page, the client side changes you make in the TextBox (via the Javascript) is retained across postback.

This behaviour is by design in ASP.NET 2.0 and it has been designed with the idea that a ReadOnly TextBox shouldnt be modified in the client side by a malicious code.

Advertisements

Windows Workflow Foundation Tutorial Series From Jeo(http://joeon.net)

Intro to Windows Workflow Foundation (Part 1 of 7): Workflow in Windows Applications (Level 100)

Intro to Windows Workflow Foundation (Part 2 of 7): Simple Human Workflow Using E-mail (Level 200)

Intro to Windows Workflow Foundation (Part 3 of 7): Hosting and Communications Options in Workflow Scenarios (Level 300)

Intro to Windows Workflow Foundation (Part 4 of 7): Workflow, Messaging, and Services: Developing Distributed Applications with Workflows (Level 300)

Intro to Windows Workflow Foundation (Part 5 of 7): Developing Event Driven State Machine Workflows (Level 300)

Intro to Windows Workflow Foundation (Part 6 of 7): Extending Workflow Capabilities with Custom Activities (Level 300)

Intro to Windows Workflow Foundation (Part 7 of 7): Developing Rules Driven Workflows (Level 300)

UPDATE: Check our these two great articles by Igor.

Part 1: How to define an SMTP protocol state machine in a Workflow

part 2: Marrying PowerShell into Workflows (Part 1 of 4)

Windows Communication Foundation From Jeo(http://joeon.net)

So, here you go!  Sixty Five Videos and Virtual Labs to make you a WCF Expert !

Windows Communication Foundation Top to Bottom (Part 01 of 15): Overview

Windows Communication Foundation Top to Bottom (Part 02 of 15): Contracts 

Windows Communication Foundation Top to Bottom (Part 03 of 15): Contract Versioning

Windows Communication Foundation Top to Bottom (Part 04 of 15): Exceptions and Faults

Windows Communication Foundation Top to Bottom (Part 05 of 15): Bindings

Windows Communication Foundation Top to Bottom (Part 06 of 15): Hosting

Windows Communication Foundation Top to Bottom (Part 07 of 15): Messaging Patterns

Windows Communication Foundation Top to Bottom (Part 08 of 15): Instancing Modes

Windows Communication Foundation Top to Bottom (Part 09 of 15): Concurrency, Throughput, and Throttling

Windows Communication Foundation Top to Bottom (Part 10 of 15): Security Fundamentals

Windows Communication Foundation Top to Bottom (Part 11 of 15): Federated Security

Windows Communication Foundation Top to Bottom (Part 12 of 15): Reliable Messaging

Windows Communication Foundation Top to Bottom (Part 13 of 15): Transactions

Windows Communication Foundation Top to Bottom (Part 14 of 15): Message Queuing

Windows Communication Foundation Top to Bottom (Part 15 of 15): Extensibility

Programming the Windows Communication Foundation

The Lifetime of a Message in Windows Communication Foundation

A Sneak Preview of Windows Communication Foundation from an Early Adopter’s Perspective

Management and Diagnostics for Windows Communication Foundation

Load Balancing, Deployment, and Performance for Windows Communication Foundation

Taking Advantage of TCP/IP Reliability in SOAP

MSDN Webcast: Introduction to Windows Workflow Foundation

MSDN Webcast: Windows Communication Foundation

MSDN Webcast: In-Depth Answers to Your Questions About Windows Communication Foundation

Calling Windows Communication Foundation Services with ASP.NET AJAX Client Libraries (Part 1 of 2)

Calling Windows Communication Foundation Services with ASP.NET AJAX Client Libraries (Part 2 of 2)

 MSDN Webcast: Advanced Serialization

MSDN Webcast: Building Distributed Applications with Windows Communication Foundation 

MSDN Webcast: Building Connected Systems Using Windows Communication Foundation and Windows Workflow Foundation

Exposing Your Content as a Service Using Windows Communication Foundation

Building Powerful AJAX-Style Solutions with ASP.NET “Atlas” and Windows Communication Foundation

Extending Windows Communication Foundation

Working with Windows Communication Foundation

Windows Communication Foundation Web-Centric Capabilities in .NET Framework 3.5

Working with Operations and Calls in Windows Communication Foundation

Introducing Web Services Enhancements for Microsoft .NET (WSE) 3.0

Dissecting Contract-First Web Services

Live From Redmond: VB9 – Building Service-Oriented Applications with WCF

Migrating .NET Applications to Services Oriented Solutions with WCF

Writing Custom Channels for Windows Communication Foundation

Transactions in Distributed Solutions with Windows Communication Foundation

.NET 3.0 Series: Windows Communication Framework Overview

Transactions in Distributed Solutions with Windows Communication Foundation

Building Powerful AJAX-Style Solutions with ASP.NET “Atlas” and Windows Communication Foundation

Exposing Your Content as a Service Using Windows Communication Foundation

Web Services Interoperability with Java and J2EE Using Windows Communication Foundation (“Indigo”)

Understanding Windows Communication Foundation Contracts

Building Microsoft Windows Communication Foundation and Windows Workflow Foundation Applications with Microsoft Visual Studio Codename “Orcas”

Windows Communication Foundation, Windows Workflow Foundation, and “InfoCard” in the Public Sector

Windows Communication Foundation, Windows Workflow Foundation, and Identity in Financial Services

The Web Service Software Factory Using WCF

Windows Communication Foundation (WCF) with Justin Smith

Building Workflow-Enabled Services with Windows Communication Foundation

A Sneak Preview of Windows Communication Foundation from an Early Adopter’s Perspective

Live from PDC: A Guided Tour of “Indigo

Connecting Windows Workflow Foundations to Lotus Notes/Lotus Domino

Virtual Labs

Understanding Windows Communication Foundation Virtual Lab

Reliable and Transacted Messaging with the Windows Communication Foundation

A Server Scenario Lab with Windows Communication Foundation

WCF Introduction – Building a WCF Service

The Fundamentals of Programming the Windows Communication Foundation

Building a Windows Communication Foundation (WCF) Adapter using the WCF LOB Adapter SDK

Understanding Windows Communication Foundation Virtual Lab express

Links

http://msdn2.microsoft.com/en-us/netframework/aa663324.aspx

How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX

You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client. However there are some workarounds. To call serverside code from javascript, you will need to use AJAX, and the easiest way out, is to use the ASP.NET AJAX Extensions.
One option while using Microsoft ASP.NET AJAX is to call ASP.NET Web services (.asmx files) from the browser by using client script. The script can call a webservice containing server-based methods (Web methods) and invoke these methods without a postback and without refreshing the whole page. However this approach could be overkill sometimes, to perform the simplest of tasks. Moreover the logic needs to be kept in a separate .asmx file. We need something that is more ‘integrated’ with our solution.
The option we are going to use in this article involves PageMethods. A PageMethod is basically a public static method that is exposed in the code-behind of an aspx page and is callable from the client script. PageMethods are annotated with the [WebMethod] attribute. The page methods are rendered as inline JavaScript.
Let us explore PageMethods with an example. The example we will be discussing here may not be the best example to explain PageMethods, but it will give you an idea of how to call server side code from client side. In this example, we will be connecting to the Customers table in the Northwind database. We will have some textboxes which will accept the CustomerID and in turn return the Contact Name of that Customer. The method returning ContactName will be called whenever the textbox loses focus. We will be using the onblur event where a javascript code will take in the value(CustomerID) from the textbox. This javascript function will then call a PageMethod (server side code) which returns the ContactName without any page refresh.
I assume that you have downloaded and installed ASP.NET AJAX extensions for ASP.NET 2.0. If not, I would advise you to download the extensions from here and install it before moving ahead. At any point of time, if you find a difficulty in understanding the code, download the sample project attached with this article at the end.
Step 1: Create an ASP.NET AJAX enabled website. Go to File > New > Website > ASP.NET AJAX-Enabled Web Site. Give the solution a name and location and click Ok.
Step 2: Drag and drop 2 labels and 4 textbox controls. We will be accepting the CustomerID from the user in the 2 textboxes and displaying the ‘ContactName’ in the other two textboxes. The textboxes that will display ‘ContactName’ has some properties set that will make it appear as a label without a border. Just set the BorderStyle=None, BorderColor=Transparent and ReadOnly=True. The markup will look similar to the following:
<form id=”form1″ runat=”server”>    
        <asp:ScriptManager ID=”ScriptManager1″ runat=”server”/>
        <div>
        <asp:Label ID=”lblCustId1″ runat=”server” Text=”Customer ID 1″></asp:Label>
        <asp:TextBox ID=”txtId1″ runat=”server”></asp:TextBox><br />
            <asp:TextBox ID=”txtContact1″ runat=”server” BorderColor=”Transparent” BorderStyle=”None”
                ReadOnly=”True”></asp:TextBox><br />
        <br />
        <asp:Label ID=”lblCustId2″ runat=”server” Text=”Customer ID 2″></asp:Label>
        &nbsp;
        <asp:TextBox ID=”txtId2″ runat=”server”></asp:TextBox><br />
            <asp:TextBox ID=”txtContact2″ runat=”server” BorderColor=”Transparent” BorderStyle=”None”
                ReadOnly=”True”></asp:TextBox>&nbsp;<br />
            </div>
    </form>
Before moving ahead, we will store our connection string information in the Web.config. Add the following tag below your </configSections> tag. Remember we have created an ‘ASP.NET AJAX enabled website’. The tag </configSections> along with some other tags automatically get added to the web.config.
<connectionStrings>
            <removename=all/>
            <addname=NorthwindConnectionStringconnectionString=Data Source=(local); Initial Catalog=Northwind; Integrated Security = SSPI;/>
      </connectionStrings>
Step 3: Currently we will add a method, ‘GetContactName()’ which will accept a CustomerID and return the Contact Name information from the Northwind database, Customer table. We will then transform this method as a PageMethod.
C#
public static string GetContactName(string custid)
    {
        if (custid == null || custid.Length == 0)
            return String.Empty;
        SqlConnection conn = null;
        try
        {
            string connection = ConfigurationManager.ConnectionStrings[“NorthwindConnectionString”].ConnectionString;
            conn = new SqlConnection(connection);
            string sql = “Select ContactName from Customers where CustomerId = @CustID”;
            SqlCommand cmd = new SqlCommand(sql, conn);
            cmd.Parameters.AddWithValue(“CustID”, custid);
            conn.Open();
            string contNm = Convert.ToString(cmd.ExecuteScalar());
            return contNm;
        }
        catch (SqlException ex)
        {
            return “error”;
        }
        finally
        {
            conn.Close();
        }
    }
VB.NET
 Public Shared Function GetContactName(ByVal custid As String) As String
        If custid Is Nothing OrElse custid.Length = 0 Then
            Return String.Empty
        End If
        Dim conn As SqlConnection = Nothing
        Try
            Dim connection As String = ConfigurationManager.ConnectionStrings(“NorthwindConnectionString”).ConnectionString
            conn = New SqlConnection(connection)
            Dim sql As String = “Select ContactName from Customers where CustomerId = @CustID”
            Dim cmd As SqlCommand = New SqlCommand(sql, conn)
            cmd.Parameters.AddWithValue(“CustID”, custid)
            conn.Open()
            Dim contNm As String = Convert.ToString(cmd.ExecuteScalar())
            Return contNm
        Catch ex As SqlException
            Return “error”
        Finally
            conn.Close()
        End Try
    End Function
Step 4: We will now transform this method as a PageMethod and then call this method GetContactName() from client side code; i.e. using JavaScript. To enable the method as a PageMethod, add the attribute [WebMethod] on top of the method:
C#
[System.Web.Services.WebMethod]
public static string GetContactName(string custid)
{
}
VB.NET
<System.Web.Services.WebMethod()> _
    Public Shared Function GetContactName(ByVal custid As String) As String
   End Function
At the sametime, add the attribute EnablePageMethods=”true” to the ScriptManager as shown below:
<asp:ScriptManager ID=”ScriptManager1″ runat=”server EnablePageMethods=”true”/>
Step 5: Let us now create the JavaScript that will call this server side code. Add a javascript file called script.js to your solution (Right Click Project > Add New Item > Jscript File > Rename file to script.js). Add the following code to the javascript file.
function CallMe(src,dest)
 {    
     var ctrl = document.getElementById(src);
     // call server side method
     PageMethods.GetContactName(ctrl.value, CallSuccess, CallFailed, dest);
 }
 // set the destination textbox value with the ContactName
 function CallSuccess(res, destCtrl)
 {    
     var dest = document.getElementById(destCtrl);
     dest.value = res;
 }
 // alert message on some failure
 function CallFailed(res, destCtrl)
 {
     alert(res.get_message());
 }
Step 6: We now need to reference this JavaScript file from our aspx page and invoke the ‘CallMe()’ method whenever the textbox loses focus. To do so:
Add a reference to the javascript file in the body tag as shown below:
<body>
<script type=”text/javascript” language=”javascript” src=”script.js”> </script>
    <form id=”form1″ runat=”server”>    
………
Step 7: To invoke the methods whenever the textbox looses focus, add these lines of code in the Page_Load() event
C#
if (!Page.IsPostBack)
        {
            txtId1.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId1.ClientID + “‘, ‘” + txtContact1.ClientID + “‘)”);
            txtId2.Attributes.Add(“onblur”, “javascript:CallMe(‘” + txtId2.ClientID + “‘, ‘” + txtContact2.ClientID + “‘)”);
        }
VB.NET
If (Not Page.IsPostBack) Then
                  txtId1.Attributes.Add(“onblur”, “javascript:CallMe(‘” & txtId1.ClientID & “‘, ‘” & txtContact1.ClientID & “‘)”)
                  txtId2.Attributes.Add(“onblur”, “javascript:CallMe(‘” & txtId2.ClientID & “‘, ‘” & txtContact2.ClientID & “‘)”)
End If
As shown above, we are using the Attributes.Add that lets us add an attribute to the server control’s System.Web.UI.AttributeCollection object. The function ‘CallMe’ kept in the ‘script.js’ file will be invoked. We are passing the source and destination textboxes as parameters. The source textbox will contain the CustomerID. The CustomerID will be looked up in the Customers table and the corresponding ‘ContactName’ will be retrieved in the destination textbox.
Well that is all that is needed to invoke server side code from client side. Run the code. Type ‘ALFKI’ in the first textbox and hit the tab key. You will see that the javascript function goes ahead and calls the PageMethod GetContactName() using PageMethods.GetContactName. It passes the value of the source textbox which contains the CustomerID. The ‘ContactName’ returned is displayed in the second textbox below the first one, in our case the value displayed is ‘Maria Anders’.
Troubleshooting: ‘PageMethods Is ‘Undefined’’ error
1.    Try setting EnablePageMethods=”true” in the script manager tag
<asp:ScriptManager ID=”ScriptManager1″ runat=”server” EnablePageMethods=”true”/>
2.    Don’t add the javascript references or code in the <head /> section. Add it to the <body> tag.
<body>
<script type=”text/javascript” language=”javascript” src=”script.js”> </script>
    <form id=”form1″ runat=”server”> 
    </form>
</body>
3.    Page methods needs to be static in code behind.