2012-06-18 3 views
18

ПроблемаКак получить ключ 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); 
    } 
} 

ответ

24

После копания в исходном коде я нашел решение. Существует класс, называемый 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); 
} 
+4

Это хорошо, но только что нашел еще одно сообщение, которое обертывает эту логику в приятном методе расширения: http://stackoverflow.com/a/12689563/1825109 – Michael12345

0

Вы должны обрамляют ключ (имя входного элемента) внутри контроллера на основе о том, как вы выполняете f ields в форме.

Для примера. если проверка второго элемента в коллекции FreeFieldsCreateFieldsModel не удалась, вы можете сфотографировать имя входного элемента i.e. key как FreeFields[1].DisplayName, где ошибка проверки будет отображаться.

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

+0

Возможно, у вас есть скрытое поле, где имя является некоторым постоянным значением, а значение поля - результатом метода EditorFor, за исключением получения атрибута name? –

Смежные вопросы