不显眼的验证不适用于自定义验证属性

时间:2014-06-26 15:15:19

标签: asp.net asp.net-mvc unobtrusive-validation

我正在尝试在MVC中编写自定义验证属性,但我无法使其作为无阻碍验证工作。它与回发(有点)工作正常,但由于表单在对话框中,我必须具有Ajax样式调用或它不可用。也许我想做的事情是无法实现的。问题是我需要连接到数据库来进行检查。

我为我的问题做了一个简单的演示。

我的模特

public class Customer
{
    public int Id { get; set; }

    [IsNameUnique]
    [Required]
    public string Name { get; set; }
}

观点:

@model WebApplication1.Models.Customer

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @id = "NewForm" }))
{
    @Html.ValidationSummary(true)

    @Html.EditorFor(m => m.Name)
    @Html.ValidationMessageFor(m => m.Name)

    <br />
    <input type="submit" value="Submit" />
}

自定义验证类

public class IsNameUnique : ValidationAttribute
{
    private CustomerRepository _repository;

    public IsNameUnique()
    {
        _repository = new CustomerRepository();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if(value != null)
        {
            var isValid = _repository.IsNameUnique(value);
            if(!isValid)
            {
                return new ValidationResult("Name must be unique");
            }
        }
        return ValidationResult.Success;
    }        
}

发布方法

[HttpPost]
    public ActionResult Index(Customer customer)
    {
        if(ModelState.IsValid)
        {
            //add customer
        }
        return View();
    }

数据库调用

class CustomerRepository
{
    internal bool IsNameUnique(object value)
    {
        //call to database
        return false;
    }
}

有一个带有名称字段的表单。我需要检查名称是否已存在于数据库中。

我的问题是如何在我的案例中进行不显眼的样式验证?我在SO上发现了关于IClientValidatable的其他帖子,但没有一个真正显示我需要做什么。即他们都没有检查数据库。感谢。

2 个答案:

答案 0 :(得分:2)

基本上&#34;不引人注意的验证&#34;意味着&#34;客户端验证,以不引人注目的方式定义&#34;。这里的关键点是&#34;客户端&#34;,即可以通过客户端浏览器中的JavaScript完成的验证。

检查名称唯一性涉及服务器端资源,虽然可以使用对服务器的AJAX请求在JavaScript中完成,但通常人们决定不这样做。

您可以按照本指南了解实施不显眼的验证的详细信息:http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

通常,您需要执行以下操作:

  1. 在web.config中启用不显眼的验证
  2. 在页面中包含jQuery,jQuery Validate和不显眼的脚本
  3. 为您的自定义验证属性
  4. 实施IClientValidatable
  5. 实施并注册自定义属性的客户端规则

答案 1 :(得分:2)

您可能需要查看[Remote]验证属性。只需创建一个返回JsonResult的控制器方法,并将其映射到远程属性。这可能是完成您要做的事情的最简单方法。

[Remote( "IsNameUnique", "Customers", HttpMethod = "post" )]
public override string Name { get; set; }


[HttpPost]
public JsonResult IsNameUnique( string name )
{
    // Code
}

如果要将其实现为自定义验证,则需要执行以下操作:

  1. 在您的属性中,实施IClientValidatable。这需要您实现GetClientValidationRules()方法。返回包含您的类型和参数的新客户端验证规则。
  2. 以下是一个例子: https://github.com/DustinEwers/dot-net-mvc-ui-demos/blob/master/ASPNET4/UIDemos/UIDemos/Attributes/PastDateOnlyAttribute.cs

    1. 然后您需要实现jQuery验证规则。这是你进行ajax通话的地方:

      jQuery.validator.addMethod("pastdateonly", function (val, element, params) {
          var value = $.trim($(element).val());
          if (value === "") return true;
      
          var maxDate = params.maxdate,
              dteVal = new Date(value),
              mxDte = new Date(maxDate);
      
          return dteVal < mxDte;
      });
      
    2. 然后添加一个不显眼的适配器方法。

      jQuery.validator.unobtrusive.adapters.add("pastdateonly", ["maxdate"],
        function (options) {
          options.rules["pastdateonly"] = {
              maxdate: options.params.maxdate
          };
          options.messages["pastdateonly"] = options.message;
        }
      );
      
    3. 实施例: https://github.com/DustinEwers/dot-net-mvc-ui-demos/blob/master/ASPNET4/UIDemos/UIDemos/Scripts/site.js