Подтвердить что ты не робот

Как получить ключ 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);
    }
}
4b9b3361

Ответ 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, где будет отображаться ошибка проверки.

Насколько я знаю, вы не можете легко получить это от контроллера.