Как получить ключ ModelState элемента в списке
Проблема
У меня есть список полей, которые пользователь может редактировать. Когда модель отправлена, я хочу проверить, действительны ли эти элементы. Я не могу использовать данные, потому что у каждого поля есть другой процесс проверки, который я не буду знать до выполнения. Если проверка не выполняется, я использую ModelState.AddModelError(string key, string error)
, где ключ - это имя элемента html, к которому вы хотите добавить сообщение об ошибке. Поскольку есть список полей, имя, которое Razor генерирует для элемента html, похоже на Fields[0].DisplayName
. Мой вопрос: есть ли способ или способ получить ключ сгенерированного имени html из модели представления?
Попытка решения
Я попробовал метод toString()
для ключа без везения. Я также просмотрел класс HtmlHelper
, но не нашел полезных методов.
Фрагмент кода
Показать модель
public class CreateFieldsModel
{
public TemplateCreateFieldsModel()
{
FreeFields = new List<FieldModel>();
}
[HiddenInput(DisplayValue=false)]
public int ID { get; set; }
public IList<TemplateFieldModel> FreeFields { get; set; }
public class TemplateFieldModel
{
[Display(Name="Dispay Name")]
public string DisplayName { get; set; }
[Required]
[Display(Name="Field")]
public int FieldTypeID { get; set; }
}
}
контроллер
public ActionResult CreateFields(CreateFieldsModel model)
{
if (!ModelState.IsValid)
{
//Where do I get the key from the view model?
ModelState.AddModelError(model.FreeFields[0], "Test Error");
return View(model);
}
}
Ответы
Ответ 1
После копания в исходном коде я нашел решение. Существует класс под названием ExpressionHelper
, который используется для генерации имени html для поля при вызове EditorFor()
. Класс ExpressionHelper
имеет метод GetExpressionText()
, который возвращает строку, которая является именем этого элемента html. Вот как его использовать...
for (int i = 0; i < model.FreeFields.Count(); i++)
{
//Generate the expression for the item
Expression<Func<CreateFieldsModel, string>> expression = x => x.FreeFields[i].Value;
//Get the name of our html input item
string key = ExpressionHelper.GetExpressionText(expression);
//Add an error message to that item
ModelState.AddModelError(key, "Error!");
}
if (!ModelState.IsValid)
{
return View(model);
}
Ответ 2
Вы должны создать ключ (имя элемента ввода) внутри контроллера, основываясь на том, как вы визуализируете поля в форме.
Например, если проверка второго элемента в FreeFields
коллекции CreateFieldsModel
не удалась, вы можете сфотографировать имя входного элемента i.e. key как FreeFields[1].DisplayName
, где будет отображаться ошибка проверки.
Насколько я знаю, вы не можете легко получить это от контроллера.