Как повторно проверить мою модель в пользовательском связывателе модели, унаследованном от DefaultModelBinder после ее изменения? - PullRequest
3 голосов
/ 15 февраля 2012

У меня есть пользовательское связывание модели, наследуемое от DefaultModelBinder. Я хочу установить свойство модели, которое не может быть разрешено с помощью DefaultModelBinder. Это выглядит так:

public class FooModelBinder : DefaultModelBinder  {
  public override void BindModel(ControllerContext controllerContext, ModelBindingContext modelBindingContext) 
  {
    var model = base.BindModel(controllerContext, bindingContext);
    ((IFooModel)model).Bar = GetBarFromSomewhere();

    return model;
  }
}

Однако, поскольку свойство Bar в IFooModel не может быть пустым, и я использую FluentValidation с правилом, гласящим, что ModelState будет недействительным после того, как я вызвал base.BindModel.

Поэтому я бы хотел избежать проверки модели при вызове base.BindModel или хотя бы очистить ошибки и повторно проверить модель после того, как я установил свойство Bar.

Я пытался разрешить валидаторы и проверить модель, но я не могу заставить ее фактически выполнить валидацию, и это не приводит к каким-либо ошибкам (даже когда это должно произойти):

var validators = bindingContext.ModelMetadata.GetValidators(controllerContext);
foreach(var validator in validators) {
    foreach (var result in validator.Validate(model)) {
        bindingContext.ModelState.AddModelError(result.MemberName, result.Message);
    }
}

После запуска этого до того, как я верну модель, validators содержит FluentValidationModelValidator, но когда я вызываю validator.Validate, я не получаю никаких ошибок. У меня есть другое свойство в моей модели, которое вызывало ошибку при запуске base.BindModel ранее, поэтому я ожидаю, что такая же ошибка произойдет здесь.

1 Ответ

4 голосов
/ 16 февраля 2012

Вместо переопределения метода BindModel вы можете попробовать переопределить метод BindProperty:

public class FooModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.Name == "Bar")
        {
            var model = bindingContext.Model as IFooModel;
            if (model != null)
            {
                model.Bar = GetBarFromSomewhere();
            }
        }
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
}
...