Могу ли я автоматически запустить проверку модели внутри пользовательского связывателя модели?

У меня есть сложный объект, который я связываю с формой. Модель переплета выглядит так:

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.

В дополнение к моему заглавному вопросу, это поднимает пару вопросов:

  1. Почему TryValidateModel(ModelState) не проверять форму, когда ModelState имеет ссылку на тот же экземпляр формы, которая TryValidateModel(form) правильно проверяет?

  2. Почему TryValidateModel(form) вызывать ценность ModelState.IsValid быть обновленным?

  3. В общем, почему связыватели отвечают за обновление ModelState?

1 ответ

Ответственность ModelBinder состоит в том, чтобы связать значения из запроса с используемыми вами моделями.

Свойство ModelState - это просто словарь, содержащий текущее состояние ваших моделей. Посмотрите на модельное состояние как список ошибок.

Когда у вас есть собственный ModelBinder, вы отображаете значения из запроса в класс по вашему выбору. Это будет в качестве параметра в ваш метод действия.

Я бы не согласился с вами, что связыватели моделей отвечают за обновление ModelState, так как ModelBinder запускается, когда он связывает значения, он все равно может иметь IsValid = true, прежде чем вы запустите TryValidateModel.

Когда вы позже запустите TryValidateModel (или ValidateModel в этом отношении), он обновит свойство ModelState с любыми ошибками, которые у вас есть. Вы также можете использовать различные типы методов проверки (DataAnnotations, IValidatableObject...)

Другие вопросы по тегам