public class Rating { public string Comment { get; set; } public int RatingLevel { get; set; } }
然后,系统管理员可以设置需要注释的RatingLevels.这些设置可通过设置服务获得.
所以,为了完全验证模型,我需要外部的信息,在这种情况下是设置服务.
到目前为止,我已经考虑过以下几点:
>将服务注入模型. DefaultModelBinder使用System.Activator创建对象,因此它不会通过正常的依赖关系解析器,并且我不能将服务注入到模型中,而不创建新的模型绑定(除此之外,这并不是正确的方式去吧)
>将服务注入注释.我还不确定这是可能的,但会进一步调查.它仍然感到笨拙.
>使用自定义模型binder.显然我可以实现OnPropertyValidating做自定义属性验证.这似乎是最好的,尽管我还不知道如何做到这一点.
哪种方法,以上或不是,最适合这种类型的验证问题?
解决方法
选项2不起作用虽然由于C#属性要求,我看不出这是怎么可能的,但这是可能的.参见以下内容:
> Resolving IoC Container Services for Validation Attributes in ASP.NET MVC
> NInjectDataAnnotationsModelValidatorProvider
选项3:我以前不了解,但似乎是一个非常强大的写验证器的方法是使用ModelValidator类和相应的ModelValidatorProvider.
首先,您创建自定义的ModelValidatorProvider:
public class CustomModelValidatorProvider : ModelValidatorProvider { public CustomModelValidatorProvider(/* Your dependencies */) {} public override IEnumerable<ModelValidator> GetValidators(ModelMetadata Metadata,ControllerContext context) { if (Metadata.ModelType == typeof(YourModel)) { yield return new YourModelValidator(...); } } }
ASP.NET MVC的IDependencyResolver将尝试解决上述提供程序,因此只要在您的IoC容器中注册,您就不需要执行任何其他操作.然后ModelValidator:
public class EntryRatingviewmodelValidatorMvcAdapter : ModelValidator { public EntryRatingviewmodelValidatorMvcAdapter( ModelMetadata argMetadata,ControllerContext argContext) : base(argMetadata,argContext) { _validator = validator; } public override IEnumerable<ModelValidationResult> Validate(object container) { if (/* error condition */) { yield return new ModelValidationResult { MemberName = "Model.Member",Message = "Rating is required." }; } } }
由于通过IDependencyResolver检索提供程序,并且提供程序完全控制了返回的ModelValidators,因此我很容易地注入依赖项并执行必要的验证.