У меня есть контроллер с двумя действиями:
[AcceptVerbs("GET")]
public ActionResult Add()
{
PrepareViewDataForAddAction();
return View();
}
[AcceptVerbs("POST")]
public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
{
if (ViewData.ModelState.IsValid)
{
GigManager.Save(gig);
return RedirectToAction("Index", gig.ID);
}
PrepareViewDataForAddAction();
return View(gig);
}
Как видите, когда форма публикует свои данные, действие Add использует GigBinder (реализация IModelBinder)
В этой папке у меня есть:
if (int.TryParse(bindingContext.HttpContext.Request.Form["StartDate.Hour"], out hour))
{
gig.StartDate.Hour = hour;
}
else
{
bindingContext.ModelState.AddModelError("Doors", "You need to tell us when the doors open");
}
Форма содержит текстовое поле с идентификатором StartDate.Hour.
Как вы можете видеть выше, GigBinder проверяет, ввел ли пользователь целое число в текстовое поле с идентификатором «StartDate.Hour». В противном случае ошибка модели добавляется в состояние модели с помощью AddModelError.
Поскольку свойство gigs gigs.StartDate.Hour строго типизировано, я не могу установить его значение, например, "TEST", если пользователь ввел его в текстовое поле формы.
Следовательно, я не могу установить значение gigs.StartDate.Hour, поскольку пользователь ввел строку, а не целое число.
Поскольку действие «Добавить» возвращает представление и передает модель (return View (gig);), если состояние модели недопустимо, когда форма повторно отображается с сообщениями проверки, значение «ТЕСТ» не отображается в текстовом поле. Вместо этого это будет значение по умолчанию gig.StartDate.Hour.
Как мне решить эту проблему? Я действительно застрял!





Не могли бы вы сделать это в своем методе PrepareViewDataForAddAction? ..
if (!ViewData.ModelState.IsValid)
{
ViewData["StartDate.Hour"] = "Error";
}
Остальные поля формы по-прежнему будут заполняться в зависимости от свойств объекта Gig.
Я думаю, вам нужно сначала выполнить базовую проверку на стороне клиента. не позволяйте ему отправлять сообщения на сервер.
Я думаю, проблема в том, что ваша ViewModel недостаточно точно соответствует вашему View. В MVC действительно важно, чтобы ваша ViewModel как можно точнее соответствовала вашему View.
В вашей ViewModel вы предполагаете целое число, но в вашем View вы используете TextBox для визуализации свойства, что позволяет использовать любой текст. Здесь есть несоответствие, и трудности, с которыми вы сталкиваетесь, пытаясь их сопоставить, являются симптомом несоответствия.
Я думаю, вам стоит либо:
1. Измените тип свойства ViewModel на строку, а затем выполните проверку в контроллере, чтобы убедиться, что введенная строка действительно является числом или:
2. Измените элемент управления, отображаемый в представлении, на элемент управления, который позволит вводить только число с помощью пользовательского элемента управления или проверки Javascript (как рекомендует @Qun Wang).
Лично я бы рекомендовал вариант 1. Таким образом, ViewModel не зависит от реализации View.