C# 为什么不是';无法验证在我的IValidatableObject上被调用?
我有一个视图模型:C# 为什么不是';无法验证在我的IValidatableObject上被调用?,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个视图模型: public class SelectVendorViewModel : IValidatableObject { [Display(Name = "Document Date")] [RequiredUnless("IsPidDv")] public DateTime? DocumentDate { get; set; } [Display(Name = "Document Number")] [RequiredUnless("Is
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);
}
}
活页夹运行正常,我可以在调试器中逐步完成它。但是永远不会调用SelectVendorViewModel.Validate
方法。属性验证通过,如果我在控制器操作ModelState.IsValid
中设置断点,则为true。我认为这可能与自定义的requiredInspect
annotation有关,但即使我删除它们,验证也不起作用。我在这个应用程序的很多地方都使用相同的模式,但这是唯一一个不起作用的模式。我能找到的唯一区别是required,除非annotation,我能够排除这一点。我错过了什么
编辑:以下是注册模型绑定器的方式:
自定义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;
}
}
在Ninject配置中:
kernel.Bind<IModelBinder<SelectVendorViewModel>>().To<SelectVendorViewModelBinder>();
kernel.Bind().To();
哦(不好意思)您没有调用ModelBinder
的基本方法,后者反过来调用模型上的Validate方法
如果模拟此调用:var salesReport=\u uow.SalesReportRepository.GetSalesReport(model.VendorId.Value、model.DocumentNumber.Value、model.DocumentDate.Value);to var salesReport=new MockSalesReport();然后它会调用validate吗?或者只是替换所有变量salesReport=\u uow.SalesReportRepository.GetSalesReport(model.VendorId.Value、model.DocumentNumber.Value、model.DocumentDate.Value);如果(salesReport!=null){model.SalesReportId=salesReport.Id;}具有model.SalesReportId=new Guid();为了测试。感谢您的建议,我们尝试了一下,但仍然没有很好地调用它。一般来说,当MVC验证模型时,它会运行DataAnnotation属性,如果其中任何属性失败,它将不会调用Validate方法,因为Validate方法通常会对数据库进行昂贵的调用以进行业务规则验证,因此,当注释等简单的事情失败时,缩短验证时间是有意义的,这样就不会浪费时间和资源来验证更大的事情,但鉴于您的模型如此简单。。。。我看不到任何明显的东西。我也是,我被卡住了:(哈哈,我其实只是在打我自己的答案,我想我们同时看到了。总是一些简单的我忽略的事情让我难堪。谢谢你的帮助!
[HttpPost]
public virtual ActionResult SelectVendor(SelectVendorViewModel selectVendorVM)
{
selectVendorVM.Vendors = GetVendors();
if (!ModelState.IsValid)
{
return View(selectVendorVM);
}
return RedirectToAction(MVC.Licensing.Endorsements.Create(selectVendorVM.SalesReportId));
}
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;
}
}
ModelBinderProviders.BinderProviders.Add(new GenericModelBinder());
kernel.Bind<IModelBinder<SelectVendorViewModel>>().To<SelectVendorViewModelBinder>();
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);
}