UPDATE:
Now it's very simple to add html attributes to default editor templates. Means instead of doing this:
@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })
you simply can do this:
@Html.EditorFor(m => m.userCode, new { htmlAttributes = new { @readonly="readonly" } })
Benefits: You haven't to call .TextBoxFor etc. for templates. Just call .EditorFor.
While @Shark's solution works correctly and it is simple and useful, my solution (that I use always) is this one Create an editor-template that can handles readonly attribute:
Create a folder named EditorTemplates in ~/Views/Shared/
Create a razor PartialView named String.cshtml
Fill the String.cshtml with this code:
@if(ViewData.ModelMetadata.IsReadOnly) {
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
new { @class = "text-box single-line readonly", @readonly = "readonly", disabled = "disabled" })
} else {
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
new { @class = "text-box single-line" })
}
In model class, put the [ReadOnly(true)] attribute on properties which you want to be readonly.
e.g.
public class Model {
// [your-annotations-here]
public string EditablePropertyExample { get; set; }
// [your-annotations-here]
[ReadOnly(true)]
public string ReadOnlyPropertyExample { get; set; }
}
Now you can use razor's default syntax simply:
@Html.EditorFor(m => m.EditablePropertyExample)
@Html.EditorFor(m => m.ReadOnlyPropertyExample)
The first one, renders a normal text-box like this:
and the second, will render to;
You can use this solution for any type of data (DateTime, DateTimeOffset, DataType.Text, DataType.MultilineText and so on). Just create an editor-template.