int数据类型的服务器端validation

我做了自定义Validator属性

partial class DataTypeInt : ValidationAttribute { public DataTypeInt(string resourceName) { base.ErrorMessageResourceType = typeof(blueddPES.Resources.PES.Resource); base.ErrorMessageResourceName = resourceName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { string number = value.ToString().Trim(); int val; bool result = int.TryParse(number,out val ); if (result) { return ValidationResult.Success; } else { return new ValidationResult(""); } } } 

但是当我在文本框中输入字符串而不是int值时,则value==null ,当我输入int值时,则value==entered value; 。 为什么?

是否有任何替代我可以实现相同(仅在服务器端确保)

发生这种情况的原因是模型绑定器( 任何validation器之前运行)无法将无效值绑定到整数。 这就是为什么你的validation器内部没有任何价值。 如果您希望能够validation这一点,您可以为整数类型编写自定义模型绑定器。

以下是这种模型绑定器的外观:

 public class IntegerBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); int temp; if (value == null || string.IsNullOrEmpty(value.AttemptedValue) || !int.TryParse(value.AttemptedValue, out temp) ) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "invalid integer"); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value); return null; } return temp; } } 

你将在Application_Start注册它:

 ModelBinders.Binders.Add(typeof(int), new IntegerBinder()); 

但您可能会问:如果我想自定义错误消息该怎么办? 毕竟,这就是我首先想要实现的目标。 编写此模型绑定器的重点是,默认情况下已经为我做了,只是因为我无法自定义错误消息?

嗯,这很容易。 您可以创建一个自定义属性,用于装饰您的视图模型,其中包含错误消息,在模型绑定器中,您将能够获取此错误消息并使用它。

所以,你可以有一个虚拟validation器属性:

 public class MustBeAValidInteger : ValidationAttribute, IMetadataAware { public override bool IsValid(object value) { return true; } public void OnMetadataCreated(ModelMetadata metadata) { metadata.AdditionalValues["errorMessage"] = ErrorMessage; } } 

您可以用来装饰您的视图模型:

 [MustBeAValidInteger(ErrorMessage = "The value {0} is not a valid quantity")] public int Quantity { get; set; } 

并调整模型绑定器:

 public class IntegerBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); int temp; var attemptedValue = value != null ? value.AttemptedValue : string.Empty; if (!int.TryParse(attemptedValue, out temp) ) { var errorMessage = "{0} is an invalid integer"; if (bindingContext.ModelMetadata.AdditionalValues.ContainsKey("errorMessage")) { errorMessage = bindingContext.ModelMetadata.AdditionalValues["errorMessage"] as string; } errorMessage = string.Format(errorMessage, attemptedValue); bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value); return null; } return temp; } }