如果需要模型外部的信息才能进行验证,那么验证模型的好方法是什么?例如,请考虑以下模型:
public class Rating {
public string Comment { get; set; }
public int RatingLevel { get; set; }
}
然后,系统管理员可以设置需要注释的RatingLevels
。这些设置可通过设置服务获得。
因此,为了完全验证模型,我需要外部信息,在这种情况下是设置服务。
到目前为止,我已经考虑了以下内容:
哪种方法,无论上述与否,最适合此类验证问题?
答案 0 :(得分:14)
选项1不合适。唯一可行的方法是通过服务定位器反模式拉入依赖项。
选项2 不起作用。虽然由于C#属性要求我无法看到这是如何可能的,但这是可能的。请参阅以下内容以获取参考:
选项3:我之前不知道这一点,但似乎是一种非常强大的编写验证器的方法是使用ModelValidator类和相应的{{3 }}
首先,您创建自定义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的ModelValidatorProvider将尝试解析上述提供程序,因此只要它已在您的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
检索提供程序并且提供程序完全控制返回的ModelValidator
时,我很容易注入依赖项并执行必要的验证。
答案 1 :(得分:5)
您可以尝试fluent validation。它支持asp.net mvc和DI,因此您可以将外部服务注入验证器。
答案 2 :(得分:1)
假设您希望根据服务返回的值对模型进行客户端和服务器端验证,我会选择2.,将服务注入注释。
我在回复this question about adding validators to a model时提供了一些示例代码。在您的情况下,唯一的另一步是您需要将您的服务注入继承自DataAnnotationsModelValidatorProvider
的类。
答案 3 :(得分:0)
如何简单地使用IValidateableObject并在该方法中确定验证是否合适并在那里设置错误?