Asp.net mvc 自定义验证属性-有效整数
我有一个奇怪的要求 我有一个类,上面有两个属性,如下所示:Asp.net mvc 自定义验证属性-有效整数,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,我有一个奇怪的要求 我有一个类,上面有两个属性,如下所示: public class MyViewModel { [EnhancedServiceValidInteger("Name")] public int NumberOfItems { get; set; } public string Name { get; set; } } 上面的类用作用于构建动态表单的动态字段。当NumberOfItems不正确(不是有效的整数)时,应使用Name属性中的值作为Displ
public class MyViewModel
{
[EnhancedServiceValidInteger("Name")]
public int NumberOfItems { get; set; }
public string Name { get; set; }
}
上面的类用作用于构建动态表单的动态字段。当NumberOfItems不正确(不是有效的整数)时,应使用Name属性中的值作为DisplayName来显示错误消息,并且是任何错误消息的输出
我已经实现了一个触发的自定义验证属性,但是如果用户输入了一个字母,我希望该属性能够拾取该字母。在这种情况下(IsValid(object value,…)IsValid methods value属性始终为0,因此验证通过,并且MyCustomValidIntegerValidator中没有断点被命中。如果是在UI中输入的值,为什么不将该值设置为“aaa”
有人能帮忙吗
我具有以下自定义验证属性:
[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);
}
}
}
公共类MyCustomValidIntegerValidator:DataAnnotationsModelValidator
{
公共MyCustomValidIntegerValidator(ModelMetadata元数据、ControllerContext上下文、EnhancedServiceValidInteger属性)
:base(元数据、上下文、属性)
{
如果(!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);
}
}
}
关于为什么在将表单值发布回控制器时,DefaultModelBinder
首先将值绑定到属性(使用PropertyDescriptor
的SetValue()
方法)。由于属性为int
,且值为string
,因此无法对其进行设置并指定默认值。直到这个绑定完成,验证过程才开始
不确定如何实现所需,但创建自定义的
ModelBinder
可能是一个选项如果您使用常用的EditorFor()
Html帮助程序创建输入字段,请注意,它还将使用required
创建一个type=“number”
输入。如果您在其中添加字母,某些浏览器将不会返回值。谢谢Tallmaris,我正在使用@Html.TextboxFor(…)。谢谢Stephen,我将查看模型绑定。您可能还需要将CustomModelBinderAttribute
应用于属性NumberOfItems
,这会告诉ModelBinder
仅将自定义ModelBinder
用于此属性(您可能不想将其应用于int
类型的所有属性)。您有任何示例吗?我的Google Fu让我担心的不是这种情况,但是ModelBinder
有很多方法可以覆盖,比如OnModelUpdating()
,你应该能够在绑定之前获取发布的值,以及OnPropertyValidating()
,这在验证之前发生,可能允许你改变行为