我有一点奇怪的要求。
我有一个有2个属性的类,如下所示:
public class MyViewModel
{
[EnhancedServiceValidInteger("Name")]
public int NumberOfItems { get; set; }
public string Name { get; set; }
}
上面的类用作构建动态表单的动态字段。当NumberOfItems不正确(不是有效整数)时,应使用Name属性中的值作为DisplayName显示错误消息,并且是任何错误消息的输出。
我已经实现了触发的自定义验证属性,但如果用户输入了一封信,我希望该属性可以选择该属性。在这种情况下(IsValid(对象值,...)),IsValid方法的value属性始终为0,因此验证通过,并且MyCustomValidIntegerValidator中没有任何断点被命中。为什么价值不会被设置为' aaa'如果这是在UI中输入的内容?
有人可以帮忙吗?
我有以下自定义验证属性:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false)]
public class MyCustomValidInteger : ValidationAttribute
{
private readonly string _validationNameFromProperty;
public EnhancedServiceValidInteger(string validationNameFromProperty) : base("{0} contains invalid character.")
{
_validationNameFromProperty = validationNameFromProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// the the other property
var property = validationContext.ObjectType.GetProperty(_validationNameFromProperty);
// check it is not null
if (property == null)
{
return new ValidationResult(String.Format("Unknown property: {0}.", _validationNameFromProperty));
}
// get the other value
var nameToUse = property.GetValue(validationContext.ObjectInstance, null).ToString();
if (value == null || value.ToString().Length == 0)
{
return ValidationResult.Success;
}
int i;
var errorMessage = string.Format("The value '{0}' is not valid for {1}", value, nameToUse);
ValidationResult validationResult = !int.TryParse(value.ToString(), out i) ? new ValidationResult(errorMessage) : ValidationResult.Success;
return validationResult;
}
}
以下是上述类的DataAnnotationsModelValidator实现:
public class MyCustomValidIntegerValidator : DataAnnotationsModelValidator<MyCustomValidInteger>
{
public MyCustomValidIntegerValidator(ModelMetadata metadata, ControllerContext context, EnhancedServiceValidInteger attribute)
: base(metadata, context, attribute)
{
if (!attribute.IsValid(context.HttpContext.Request.Form[metadata.PropertyName]))
{
var propertyName = metadata.PropertyName;
context.Controller.ViewData.ModelState[propertyName].Errors.Clear();
context.Controller.ViewData.ModelState[propertyName].Errors.Add(attribute.ErrorMessage);
}
}
}
答案 0 :(得分:1)
至于为什么,当表单值发布回控制器时,DefaultModelBinder
首先将值绑定到属性(使用SetValue()
PropertyDescriptor
方法)。由于属性为int
且值为string
,因此无法设置并分配默认值。直到此绑定完成,验证过程才开始。
不确定如何实现您想要的效果,但创建自定义ModelBinder
可能是一个选项