2015-03-02 2 views
0

У меня есть вид модели:Почему не выполняется проверка на мой IValidatableObject?

public class SelectVendorViewModel : IValidatableObject 
{ 
    [Display(Name = "Document Date")] 
    [RequiredUnless("IsPidDv")] 
    public DateTime? DocumentDate { get; set; } 

    [Display(Name = "Document Number")] 
    [RequiredUnless("IsPidDv")] 
    public int? DocumentNumber { get; set; } 

    [Display(Name = "Vendor")] 
    [RequiredUnless("IsPidDv")] 
    public Guid? VendorId { get; set; } 

    public List<SelectListItem> Vendors { get; set; } 

    [Display(Name="PID/DV")] 
    public bool IsPidDv { get; set; } 

    public Guid? SalesReportId { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     return SelectVendorViewModelValidator.ValidateSalesReport(validationContext, this); 
    } 
} 

Пользовательская модель Связующее:

internal class SelectVendorViewModelBinder : DefaultModelBinder, IModelBinder<SelectVendorViewModel> 
{ 
    private readonly IVendorUnitOfWork _uow; 

    public SelectVendorViewModelBinder(IVendorUnitOfWork uow) 
    { 
     _uow = uow; 
    } 

    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var model = bindingContext.Model as SelectVendorViewModel; 

     if (model == null || !model.VendorId.HasValue || !model.DocumentDate.HasValue || !model.DocumentNumber.HasValue) 
     { 
      return; 
     } 

     var salesReport = _uow.SalesReportRepository.GetSalesReport(model.VendorId.Value, model.DocumentNumber.Value, 
      model.DocumentDate.Value); 
     if (salesReport != null) 
     { 
      model.SalesReportId = salesReport.Id; 
     } 
    } 
} 

И валидатор:

internal class SelectVendorViewModelValidator 
{ 
    internal static IEnumerable<ValidationResult> ValidateSalesReport(ValidationContext validationContext, SelectVendorViewModel viewModel) 
    { 
     if (viewModel.IsPidDv) 
     { 
      yield break; 
     } 

     if (!viewModel.SalesReportId.HasValue || viewModel.SalesReportId.Value == default(Guid)) 
     { 
      yield return new ValidationResult("Sales report document does not exist."); 
     } 
    } 
} 

И действие контроллера, который в настоящее время размещен на:

[HttpPost] 
public virtual ActionResult SelectVendor(SelectVendorViewModel selectVendorVM) 
{ 
    selectVendorVM.Vendors = GetVendors(); 
    if (!ModelState.IsValid) 
    { 
     return View(selectVendorVM); 
    }   

    return RedirectToAction(MVC.Licensing.Endorsements.Create(selectVendorVM.SalesReportId)); 
} 

Связующее работает правильно, я могу пройти через него в отладчике. Но метод SelectVendorViewModel.Validate никогда не называется. Проверка свойств проходит, и если я устанавливаю точку останова в действии контроллера, то значение ModelState.IsValid истинно. Я думал, что это может быть что-то с аннотацией RequiredUnless, но даже когда я удаляю их, проверка не работает. Я использую этот же шаблон во многих местах этого приложения, но это единственный, который не работает. Единственное различие, которое я мог найти между этим и остальными, - это аннотация RequiredUnless, и я смог это исключить. Что мне не хватает?

EDIT: Вот как я зарегистрировать модели вяжущие:

Пользовательские IModelBinderProvider:

public class GenericModelBinder : IModelBinderProvider 
{ 
    public IModelBinder GetBinder(Type modelType) 
    { 
     var genericBinder = typeof(IModelBinder<>).MakeGenericType(modelType); 

     var binder = DependencyResolver.Current.GetService(genericBinder) as IModelBinder; 

     return binder; 
    } 
} 

В Global.asax метода Application_Start:

ModelBinderProviders.BinderProviders.Add(new GenericModelBinder()); 

И в конфигурации Ninject:

kernel.Bind<IModelBinder<SelectVendorViewModel>>().To<SelectVendorViewModelBinder>(); 
+0

Если вы издеваться этот вызов: вар salesReport = _uow.SalesReportRepository.GetSalesReport (model.VendorId.Value, model.DocumentNumber.Value, model.DocumentDate.Value); to var salesReport = new MockSalesReport(); он вызывает подтверждение? – rism

+0

Или иначе просто замените все это var salesReport = _uow.SalesReportRepository.GetSalesReport (model.VendorId.Value, model.DocumentNumber.Value, model.DocumentDate.Value); if (salesReport! = Null) { модель.SalesReportId = salesReport.Id; } с моделью. SalesReportId = new Guid(); для тестирования. – rism

+0

Спасибо за предложение, просто попробовал его, и он все равно не вызван –

ответ

1

О (сжимать), вы не вызываете базовый метод ModelBinder, который, в свою очередь, вызывает метод Validate модели. ;)

protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var model = bindingContext.Model as SelectVendorViewModel; 

     if (model == null || !model.VendorId.HasValue || !model.DocumentDate.HasValue || !model.DocumentNumber.HasValue) 
     { 
      return; 
     } 

     var salesReport = _uow.SalesReportRepository.GetSalesReport(model.VendorId.Value, model.DocumentNumber.Value, 
      model.DocumentDate.Value); 
     if (salesReport != null) 
     { 
      model.SalesReportId = salesReport.Id; 
     } 
     // this is important as we overrode but still need base 
     // functionality to effect a validate 
     base.OnModelUpdated(controllerContext, bindingContext); 
    } 
+0

Ха-ха, я на самом деле просто набрал свой собственный ответ, я думаю, мы видели его одновременно. Это всегда что-то простое, я упускаю из виду то, что меня озадачивает. Спасибо за помощь! –

+0

Веселый действительно! – rism

Смежные вопросы