Могу ли я автоматически запустить проверку модели внутри пользовательского связывателя модели?
У меня есть сложный объект, который я связываю с формой. Модель переплета выглядит так:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var form = new MyForm();
var myObject = ...; //try to load up the object
/* logic to populate values on myObject */
form.MyObject = myObject;
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, new ValueProviderResult(form, "", CultureInfo.CurrentUICulture));
return form;
}
и он делает то, что должен; Я получаю правильно заселенный MyForm
из него и ссылка на тот же экземпляр MyForm включена в ModelState. Тем не менее, форма не проходит проверку с использованием DataAnnotations
или мой CustomValidation
Проверка. Для того, чтобы вызвать эту проверку, я должен добавить TryValidateModel()
позвоните в мой контроллер:
[HttpPost]
public ActionResult ProcessMyForm(MyForm form)
{
//ModelState has the MyForm instance inside of it
//TryValidateModel(ModelState); //this does not work
TryValidateModel(form); //this works
if (!ModelState.IsValid)
{
return View("Complete", form);
}
return RedirectToAction("Index");
}
Что не только вызывает мою пользовательскую проверку, но также обновляет значение ModelState.IsValid.
В дополнение к моему заглавному вопросу, это поднимает пару вопросов:
Почему
TryValidateModel(ModelState)
не проверять форму, когдаModelState
имеет ссылку на тот же экземпляр формы, котораяTryValidateModel(form)
правильно проверяет?Почему
TryValidateModel(form)
вызывать ценностьModelState.IsValid
быть обновленным?В общем, почему связыватели отвечают за обновление
ModelState
?
1 ответ
Ответственность ModelBinder состоит в том, чтобы связать значения из запроса с используемыми вами моделями.
Свойство ModelState - это просто словарь, содержащий текущее состояние ваших моделей. Посмотрите на модельное состояние как список ошибок.
Когда у вас есть собственный ModelBinder, вы отображаете значения из запроса в класс по вашему выбору. Это будет в качестве параметра в ваш метод действия.
Я бы не согласился с вами, что связыватели моделей отвечают за обновление ModelState, так как ModelBinder запускается, когда он связывает значения, он все равно может иметь IsValid = true, прежде чем вы запустите TryValidateModel.
Когда вы позже запустите TryValidateModel (или ValidateModel в этом отношении), он обновит свойство ModelState с любыми ошибками, которые у вас есть. Вы также можете использовать различные типы методов проверки (DataAnnotations, IValidatableObject...)