Могу ли я автоматически запустить проверку модели внутри пользовательского связывателя модели? - PullRequest
2 голосов
/ 25 февраля 2011

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

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 или my 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 Ответ

1 голос
/ 10 марта 2011

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

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

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

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

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

...