Scott on Writing

Musings on technical writing...

ReadOnly vs. Enabled in Version 1.x and Version 2.0 for ViewState-Disabled Forms

All ASP.NET Web controls have the Enabled property, which, when set to False, renders the associated HTML element as “disabled,” which grays it out and prohibits the user from interacting with the control. For example, in IE a disabled TextBox's text is grayed out and the user cannot focus on the TextBox, change its value, etc. (In FireFox, the text and background of the TextBox are both grayed out.) Often, web developers will use the Enabled property when displaying a read-only or locked data input screen.

However, if you examine the TextBox class you'll find a ReadOnly property in addition to Enabled, which can understandably be a bit confusing especially considering that the other standard input Web controls - the CheckBox, RadioButton, DropDownList, RadioButtonList, CheckBoxList, ListBox, etc. - lack the ReadOnly property and offer only Enabled. If you set the ReadOnly property to True for the TextBox you'll find that the text/background is not grayed out (as with setting Enabled to False), but that the text content is uneditable (as expected per the property's name).

So what's the difference between these two properties and why do both exist? There are two differences between these two properties, a trivial difference and a subtle, profound one:

  1. The two properties emit different markup. When you set Enabled to False, the TextBox injects the attribute disabled="disabled" into its rendered HTML. When you set the ReadOnly property to True, the attribute readonly="readonly" is injected.
  2. According to the W3C spec on HTML forms, disabled controls are NOT "successful," while read-only controls MAY BE "successful." A "successful" control is one whose name/value pair is sent back to the browser through the POST headers or querystring. Therefore, disabled controls are NOT sent back to the ASP.NET page, while read-only controls may be, depending on the User Agent. (In my tests, both IE 6 and FireFox 1.5 send along the read-only TextBox input.)

For most scenarios, this subtle difference in postback between read-only and disabled controls is not an issue... it becomes an issue, however, when using these controls in a page with its ViewState turned off and when these control values are set programmatically.

Since disabled input control values are not sent back when the form is submitted, the only way that the page can remember these values is if they are specified statically (i.e., specified directly in the markup portion of the ASP.NET page in the TextBox control's declarative syntax) or if they are set programmatically and ViewState is enabled for the control and page. If ViewState is disabled and the control value is specified programmatically, it will be lost on postback because the actual value in the disabled TextBox won't be sent back to the server (because it's not a “successful” control) and the server won't remember the value in ViewState since ViewState is disabled).

If you encountered this problem in ASP.NET version 1.x you might have found the TextBox's ReadOnly property and used that instead of setting Enabled to False. You could still have a page's ViewState disabled and set a read-only TextBox Web control's Text property programmatically because the TextBox value is sent back through the form submission for read-only controls. However, in ASP.NET version 2.0, things change just a bit, as noted by Rick Strahl in his blog entry ASP.NET 2.0 ReadOnly behavior change when EnableViewState is false. With 2.0, the TextBox control's ReadOnly property's behavior has changed slightly. From the technical docs:

The Text value of a TextBox control with the ReadOnly property set to true is sent to the server when a postback occurs, but the server does no processing for a read-only text box. This prevents a malicious user from changing a Text value that is read-only. The value of the Text property is preserved in the view state between postbacks unless modified by server-side code.

What happens is that the client sends along the value of the read-only TextBox through the form values, but the ASP.NET 2.0 engine does not take that value and assign it to the Text property of the TextBox on postback to help protect against a malicious user changing the read-only TextBox value themselves. But this brings us back to our earlier problem - if the value isn't specified in the postback (or is ignored, in this case) and ViewState is disabled, the value will be lost. Eep.

Rick's workaround was to just manually read the value from the request headers (this.TextBox1.Text = Request[this.TextBox1.UniqueID];), which poses a security risk and introduces the problem that 2.0 addresses. The optimal approach is to requery the value from the database (or wherever you initially got the programmatically-set value for the read-only TextBox).

The moral of this blog post is that if you have read-only data you can use either disabled or read-only form fields, it really doesn't matter whether or not you receive back the value of the form field in the form's submissions. It shouldn't matter because you shouldn't be trusting/using that data to begin with! If you have read-only data, don't re-read it from a data stream that the end user can tinker with!

posted on Monday, January 16, 2006 9:41 AM

Feedback

# SubmitDisabledControls - A New Property in ASP.NET 2.0 1/23/2006 1:37 PM Scott on Writing

# ASP.NET 2.0: Textbox ReadOnly Property 7/10/2007 2:20 PM Samurai Programmer.com

This has been documented in numerous places includinghere, here, here(with an incorrect fix) and here.

# Investment House 1/16/2009 10:19 PM Raymond Kirk

That's great, I never thought about ReadOnly vs. Enabled in Version 1.x and Version 2.0 for ViewState-Disabled Forms like that before.

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<July 2009>
SMTWTFS
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Comment Stats

DayTotal% of Total
Sunday 2046.9%
Monday 42314.3%
Tuesday 50116.9%
Wednesday 54518.4%
Thursday 57219.3%
Friday 53618.1%
Saturday 1856.2%
Total 2966100.0%

Hour1Total% of Total
12:00 AM 752.5%
1:00 AM 802.7%
2:00 AM 672.3%
3:00 AM 812.7%
4:00 AM 642.2%
5:00 AM 1234.1%
6:00 AM 1153.9%
7:00 AM 1755.9%
8:00 AM 1876.3%
9:00 AM 1565.3%
10:00 AM 1866.3%
11:00 AM 1926.5%
12:00 PM 1996.7%
1:00 PM 1846.2%
2:00 PM 1675.6%
3:00 PM 1344.5%
4:00 PM 1153.9%
5:00 PM 1063.6%
6:00 PM 993.3%
7:00 PM 1063.6%
8:00 PM 903.0%
9:00 PM 842.8%
10:00 PM 893.0%
11:00 PM 923.1%
Total 2966100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 4.91157
Monday 4.92379
Tuesday 4.21471
Wednesday 7.42668
Thursday 6.53666
Friday 5.17450
Saturday 4.73175
Total 5.522966

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 4.0048
8:00 AM 4.29133
9:00 AM 6.04290
10:00 AM 5.83274
11:00 AM 4.36192
12:00 PM 6.44348
1:00 PM 3.14132
2:00 PM 5.04227
3:00 PM 7.97303
4:00 PM 3.8199
5:00 PM 6.00168
6:00 PM 4.56114
7:00 PM 8.95188
8:00 PM 8.58163
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.522966

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles