Solution 1 In razor, everything is easy just add @readonly attribute to the code will do the needful.
EditorFor(model => model. userName, new { htmlAttributes = new { disabled = "disabled", @readonly = "readonly" } }) .
@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })
You are welcome to make an HTML Helper for this, but this is simply just an HTML attribute like any other. Would you make an HTML Helper for a text box that has other attributes?
UPDATE: Now it's very simple to add HTML attributes to the default editor templates. It neans 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:
EditorTemplates in ~/Views/Shared/
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.
For example,
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:
<input class="text-box single-line" id="field-id" name="field-name" />
And the second will render to;
<input readonly="readonly" disabled="disabled" class="text-box single-line readonly" id="field-id" name="field-name" />
You can use this solution for any type of data (DateTime, DateTimeOffset, DataType.Text, DataType.MultilineText and so on). Just create an editor-template.
The solution with TextBoxFor is OK, but if you don't want to see the field like EditBox stylish (it might be a little confusing for the user) involve changes as follows:
Razor code before changes
<div class="editor-field">
     @Html.EditorFor(model => model.Text)
     @Html.ValidationMessageFor(model => model.Text)
</div>
After changes
<!-- New div display-field (after div editor-label) -->
<div class="display-field">
    @Html.DisplayFor(model => model.Text)
</div>
<div class="editor-field">
    <!-- change to HiddenFor in existing div editor-field -->
    @Html.HiddenFor(model => model.Text)
    @Html.ValidationMessageFor(model => model.Text)
</div>
Generally, this solution prevents field from editing, but shows value of it. There is no need for code-behind modifications.
With credits to the previous answer by @Bronek and @Shimmy:
This is like I have done the same thing in ASP.NET Core:
<input asp-for="DisabledField" disabled="disabled" />
<input asp-for="DisabledField" class="hidden" />
The first input is readonly and the second one passes the value to the controller and is hidden. I hope it will be useful for someone working with ASP.NET Core.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With