Как создать текстовое поле только для чтения в ASP.NET MVC3 Razor

118

Как создать текстовое поле только для чтения в ASP.NET MVC3 с помощью механизма просмотра Razor?

Есть ли для этого метод HTMLHelper?

Что-то вроде следующего?

@Html.ReadOnlyTextBoxFor(m => m.userCode)
Shyju
источник

Ответы:

246
@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

Вы можете создать для этого HTML-помощник, но это просто атрибут HTML, как и любой другой. Вы бы создали помощник HTML для текстового поля с другими атрибутами?


источник
1
@Shyju Извините, мне не хватало @префикса readonlyсвойства. Смотрите мою правку.
7
В будущем, если вы получите какие-либо ошибки при добавлении свойств в аргумент динамического объекта, вы можете добавить к ним префикс @. Обычно вы видите это только с ключевыми словами, которые соответствуют атрибутам HTML (например, только для чтения, класс и т. Д.)
Брэд Кристи,
10
@BradChristie: Нет; вам нужен только @для использования атрибутов, соответствующих ключевым словам C # .
SLaks 06
1
@BradChristie: Я неправильно прочитал ваш комментарий ("ключевые слова" были двусмысленными)
SLaks
1
Если у вас есть несколько атрибутов html, вы можете сделать что-то вроде:@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly", @class="form-control" })
benscabbia
32

ОБНОВЛЕНИЕ: теперь очень просто добавлять атрибуты HTML в шаблоны редактора по умолчанию. Вместо этого нужно:

@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

вы просто можете сделать это:

@Html.EditorFor(m => m.userCode, new { htmlAttributes = new { @readonly="readonly" } })

Преимущества: Вам не нужно звонить .TextBoxForи т. Д. За шаблонами. Просто позвони .EditorFor.


Хотя решение @Shark работает правильно, простое и полезное, мое решение (которое я использую всегда) таково: создать объект, editor-templateкоторый может обрабатывать readonlyатрибут :

  1. Создайте папку с именем EditorTemplatesв~/Views/Shared/
  2. Создайте бритву с PartialViewименемString.cshtml
  3. Заполните String.cshtmlэтот код:

    @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" })
    }
  4. В классе модели поместите [ReadOnly(true)]атрибут в свойства, которыми вы хотите быть readonly.

Например,

public class Model {
    // [your-annotations-here]
    public string EditablePropertyExample { get; set; }

    // [your-annotations-here]
    [ReadOnly(true)]
    public string ReadOnlyPropertyExample { get; set; }
}

Теперь вы можете просто использовать синтаксис Razor по умолчанию:

@Html.EditorFor(m => m.EditablePropertyExample)
@Html.EditorFor(m => m.ReadOnlyPropertyExample)

Первый рендерит нормаль text-boxтак:

<input class="text-box single-line" id="field-id" name="field-name" />

А второй будет обрабатывать;

<input readonly="readonly" disabled="disabled" class="text-box single-line readonly" id="field-id" name="field-name" />

Вы можете использовать это решение для любого типа данных ( DateTime, DateTimeOffset, DataType.Text, DataType.MultilineTextи так далее). Просто создайте editor-template.

Рави Эмири
источник
2
+1, потому что вы использовали ViewData.ModelMetadata.IsReadOnly. Я ожидал, что MVC учтет эти вещи в версии 4.
cleftheris
@cleftheris ну, сейчас мы находимся в версии 5, а MVC все еще не принимал их;)
ravy amiry
2
@Javad_Amiry - отличный ответ - я реализовал его, и, похоже, он отлично работал, пока я не нажал Сохранить на странице редактирования с шаблоном. Затем оказывается, что свойства с [ReadOnly (true)] приведут к отправке в базу данных NULL вместо реального значения свойства. Вы сталкивались с этим?
Перси,
5

Решение с TextBoxFor в порядке, но если вы не хотите видеть поле типа EditBox style (это может немного сбить с толку пользователя), внесите следующие изменения:

  1. Код Razor до изменений

    <div class="editor-field">
         @Html.EditorFor(model => model.Text)
         @Html.ValidationMessageFor(model => model.Text)
    </div>
  2. После изменений

    <!-- 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>

Как правило, это решение предотвращает редактирование поля, но показывает его значение. Нет необходимости в модификации кода программной части.

Бронек
источник
1
Я думаю, что наличие CSS для поля редактора классов и поля отображения здесь может быть действительно полезным.
DOK
Что вы имеете в виду, говоря «это решение запрещает редактирование» (это кажется непонятным)? Пожалуйста, ответьте, отредактировав свой ответ , а не здесь, в комментариях (при необходимости).
Питер Мортенсен
3

С кредитами на предыдущий ответ @Bronek и @Shimmy:

Это похоже на то, что я сделал то же самое в ASP.NET Core:

<input asp-for="DisabledField" disabled="disabled" />
<input asp-for="DisabledField" class="hidden" />

Первый ввод доступен только для чтения, а второй передает значение контроллеру и скрыт. Надеюсь, это будет полезно для тех, кто работает с ASP.NET Core.

Адитья Баддула
источник
0
 @Html.TextBox("Receivers", Model, new { @class = "form-control", style = "width: 300px", @readonly = "readonly" })
Хоссейн Дар
источник
1
Объяснение было бы в порядке.
Питер Мортенсен
0
@Html.TextBoxFor(model => model.IsActive, new { readonly= "readonly" })

Это нормально для текстового поля. Однако, если вы попытаетесь сделать то же самое для, checkboxпопробуйте использовать это, если вы его используете:

@Html.CheckBoxFor(model => model.IsActive, new { onclick = "return false" })

Но не используйте disable, потому что disable всегда отправляет на falseсервер значение по умолчанию - либо оно было отмечено, либо нет. И readonlyне работает для флажка и radio button. readonlyработает только для textполей.

gdmanandamohon
источник
А как насчет раскрывающихся списков?
user3020047
Надеюсь, это поможет stackoverflow.com/questions/1636103/…
gdmanandamohon
0

Вы можете использовать приведенный ниже код для создания TextBox только для чтения.

Способ 1

 @Html.TextBoxFor(model => model.Fields[i].TheField, new { @readonly = true })

Способ 2

@Html.TextBoxFor(model => model.Fields[i].TheField, new { htmlAttributes = new {disabled = "disabled"}})
Кришан Датт Шарма
источник