EditorTemplate DropDown получает неверный идентификатор и не может быть проверен

Я сделал EditorTemplate в MVC 4 с этим кодом:

@model Drexx.Models.Account
@Html.DropDownListFor(model => model.LevelId, (IEnumerable<SelectListItem>)ViewBag.LevelId, String.Empty)

My View имеет этот код:

@Html.EditorForModel();

Моя модель имеет этот код:

[UIHint("LevelDropDown")]
[DisplayName("Level")]
public int LevelId { get; set; }
public virtual Level Level { get; set; }

Мой контроллер имеет этот код в Get:

ViewBag.LevelId = new SelectList(db.Level, "Id", "Name");

Мой Контроллер имеет этот код в Посте:

ViewBag.LevelId = new SelectList(db.Level, "Id", "Name", account.LevelId);

Вот как выглядит исходный код, когда я его запускаю:

<select data-val="true" data-val-number="The field Level must be a number." data-val-required="Feltet Level skal udfyldes." id="LevelId_LevelId" name="LevelId.LevelId">
    <option value=""></option>
    <option value="1">Normal</option>
    <option value="2">Admin</option>
</select>
<span class="field-validation-valid" data-valmsg-for="LevelId" data-valmsg-replace="true"></span>

почему он делает идентификатор выпадающего в "LevelId_LevelId" и имя в "LevelId.LevelId"? Раскрывающийся список работает и показывает, что он должен, но проверка не работает, поскольку идентификатор / имя неверны. проверка выделяет раскрывающийся список, но не отображает сообщение об ошибке.

Раскрывающийся список работал отлично, прежде чем я переместил его в EditorTemplate /, прежде чем я начал использовать EditorForModel

Я новичок в EditorTemplates, так что мне трудно понять, что может вызвать это.

2 ответа

Решение

Я нашел решение.

Модель должна выглядеть так:

[DisplayName("Level")]
[UIHint("LevelId")]
[Required]
public int? LevelId { get; set; }

Шаблон Editor должен выглядеть так:

@model int?
@Html.DropDownListFor(model => model, (IEnumerable<SelectListItem>)ViewBag.LevelId, String.Empty)

Очень важно, чтобы я поставил "?" после int, потому что у меня есть значение по умолчанию в раскрывающемся списке.

Мне не нужно было создавать ViewModel для выпадающего списка.

Вот как в итоге источник посмотрел после исправления:

<div class="editor-field">
    <select data-val="true" data-val-number="The field Level must be a number." data-val-required="Feltet Level skal udfyldes." id="LevelId" name="LevelId">
        <option value=""></option>
        <option value="1">Normal</option>
        <option value="2">Admin</option>
    </select>
    <span class="field-validation-valid" data-valmsg-for="LevelId" data-valmsg-replace="true"></span>
</div>

Спасибо за все предложения Дарину Димитрову, но они у меня не сработали.

Кажется, здесь есть некоторая путаница. Вы украсили свой LevelId целочисленное свойство с UIHint атрибут, указывающий на обычай LevelDropDown.cshtml шаблон редактора, и, тем не менее, ваш шаблон редактора, похоже, строго напечатан Drexx.Models.Account модель, которая неверна.

Давайте рассмотрим пример того, как вы могли бы этого достичь. Как всегда в ASP.NET MVC, вы начинаете с разработки модели представления, которая будет содержать необходимые свойства, которые могут потребоваться вашему представлению:

public class AccountViewModel
{
    [DisplayName("Level")]
    public int LevelId? { get; set; }

    public IEnumerable<SelectListItem> Levels { get; set; }
}

затем вы пишете действие контроллера, которое заполняет эту модель представления и передает его представлению:

public ActionResult Index()
{
    var model = new AccountViewModel();
    model.LevelId = 123; // some value that you want to be used to preselect some element of the dropdown
    model.Levels = new SelectList(db.Level, "Id", "Name");

    return View(model);
}

а затем в соответствующем представлении:

@model AccountViewModel
...
@Html.EditorForModel()

а затем в ~/Views/Shared/EditorTemplates/AccountViewModel.cshtml:

@model AccountViewModel
@Html.DropDownListFor(x => x.LevelId, Model.Levels, string.Empty)

У вас также есть возможность указать название шаблона:

@Html.EditorForModel("Foo")

который будет искать ~/Views/Shared/EditorTemplates/Foo.cshtml шаблон.

UIHint Атрибут можно использовать, когда у вас есть более сложная модель родительского представления. Например:

public class MyViewModel
{
    UIHint("LevelDropDown")
    public AccountViewModel Account { get; set; }

    ...
}
Другие вопросы по тегам