ASP.NET 4.5 自定义验证属性。 IsValid() 调用太晚了

Posted

技术标签:

【中文标题】ASP.NET 4.5 自定义验证属性。 IsValid() 调用太晚了【英文标题】:ASP.NET 4.5 Custom Validation Attribute. IsValid() called too late 【发布时间】:2016-11-30 09:57:36 【问题描述】:

我是 ASP.NET 领域的新手。我想为 viewModel 类的属性创建自定义验证。假设此验证检查输入是否为大于 10 的整数。因此在 MyViewModel.cs 文件中,我们有以下代码部分:

[GreaterThanTen]
[RegularExpression("^[0-9][0-9]*$", ErrorMessageResourceType = typeof(Resources.Resource),
        ErrorMessageResourceName = "NonNegativeIntMessage")]
[Required(ErrorMessageResourceType = typeof(Resources.Resource),
        ErrorMessageResourceName = "RequiredValidationMessage")]
[UIHint("OwTextbox")]
public int MyInt  get; set; 

是上述属性的定义,并且:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class GreaterThanTenAttribute : ValidationAttribute

    public GreaterThanTenAttribute() : base(Resources.Resource.GreaterThanTen)  

    protected override ValidationResult IsValid(Object value,ValidationContext validationContext)
    
        if (value != null)
        
            if (value is int) // check if it is a valid integer
            
                int suppliedValue = (int)value;
                if (suppliedValue > 10)
                
                    return ValidationResult.Success;

                
            

        

        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    


是用于定义验证消息的扩展 ValidationAttribute 类。

然后有一个网页包含这个表格:

<form name="my-form" id="my-form">
  <div class="form-group">
     <label for="MyObject_MyInt">My points:</label>
     <div class="form-group-inner">
         <div class="field-outer">
            @html.TextBoxFor(m => m.MyObject.MyInt, new  @class = "input-lg")
            @Html.ValidationMessageFor(m => m.MyObject.MyInt)
         </div>
      </div>
   </div>
</form>

当单击按钮时,会调用以下 javascript 函数以验证 TextBox 值并将其插入数据库...

function insertData() 
   if ($("#my-form").valid()) 
     ...
   

问题是当执行到达if ($("#my-form").valid()) 时执行所有标准验证,例如定义值应该是非负整数的正则表达式,除了自定义 IsGreaterThanTen 验证之外在验证字段并处理值后稍后调用(不确定是什么触发它)。我做错了什么?

【问题讨论】:

【参考方案1】:

您的自定义验证器是用 c# 实现的,并且处于“服务器端”状态。它没有任何相应的客户端 javascript 实现,因此实际发生的情况是您的表单被发送回运行验证器的控制器,模型验证失败,并且它发送回页面并显示验证错误。

您要做的是在服务器端,在您的控制器 httpPost 处理程序中检查验证是否成功,然后再处理 viewModel,例如:

if(ModelState.IsValid)
 PerformProcessingOf(viewModel);
 //Redirect or whatever...

else
return view(viewModel);

【讨论】:

感谢您的及时答复。不过我还有一些问题。为什么其他验证器不会发生这种情况,而是在客户端进行处理? 内置的有在 jqueryValidators js 脚本中定义的 JavaScript 实现。我不确定是否有任何扩展点允许您编写自己的自定义属性的客户端验证实现。我会对此进行调查并回复您。 我刚刚尝试了您的提议,以检查我的控制器上的 ModelState.isValid。它正在工作,尽管我现在看到由于某种原因,我的 GreaterThanTenAttribute 的 isValid() 函数中的 value 参数始终为 0。我正在研究它。如果您找到在客户端扩展我的自定义验证器的方法,请将其添加到您的答案中,以便我接受它。 嘿伙计。我发现这篇文章非常简洁地介绍了如何让客户端为您的自定义验证属性工作。享受:thewayofcode.wordpress.com/tag/custom-unobtrusive-validation

以上是关于ASP.NET 4.5 自定义验证属性。 IsValid() 调用太晚了的主要内容,如果未能解决你的问题,请参考以下文章

自定义属性的 ASP.NET MVC 客户端验证

ASP.Net Core MVC - 自定义属性的客户端验证

剃须刀页面上自定义验证属性的 ASP.NET Core 客户端验证

ASP.NET MVC3 - 自定义验证属性 -> 客户端损坏

使用 IClientModelValidator 在 ASP.NET Core 中使用参数自定义客户端验证属性

ASP.NET MVC:通过 DataAnnotation 进行自定义验证