ASP.NET MVC3:ValidationType ModelClientValidationRule

时间:2012-02-19 13:52:17

标签: jquery asp.net asp.net-mvc asp.net-mvc-3 componentmodel

我刚刚创建了一个示例MVC3应用程序来学习验证。它正在使用DataAnnotations。我创建了一个名为CustomStartLetterMatch的自定义ValidationAttribute 。它正在实现“System.Web.Mvc.IClientValidatable”。我有相应的客户端代码用不引人注目的jQuery编写。这是按预期工作的。

关于自定义验证器:它比较输入的第一个名称和姓氏。如果它们的第一个字符不相同则抛出错误。

正如我所说,该应用程序运行正常。但当我看到rule.ValidationType = "greaterdate";时,我感到困惑。我想将其更改为“anotherDefaultType”之类的其他内容。当我更改它时,它失败并出现jQuery错误。

  1. 这是什么原因?
  2. 有哪些可用的ValidationTypes?
  3. 在此场景中更改ValidationType的建议方法是什么
  4. CODE:

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Collections.Generic;
    namespace MyValidationTEST
    {
        public class Person
        {
        [Required(ErrorMessage = "First name required")]
        public string FirstName { get; set; }
    
        [CustomStartLetterMatch("FirstName")]
        [StringLength(5,ErrorMessage = "Must be under 5 characters")]
        public string LastName { get; set; }
    
        [Range(18,50,ErrorMessage="Must be between 18 and 50")]
        public int Age { get; set; }
    
    }
    
    
    
    public sealed class CustomStartLetterMatch : ValidationAttribute, System.Web.Mvc.IClientValidatable 
    {
    
        private const string _defaultErrorMessage = " First letter of '{0}' must be same as first letetr of '{1}'";
        private string _basePropertyName;
    
        public CustomStartLetterMatch(string basePropertyName)
            : base(_defaultErrorMessage)
        {
            _basePropertyName = basePropertyName;
        }
    
    
        //Override FormatErrorMessage Method
        public override string FormatErrorMessage(string name)
        {
            return string.Format(_defaultErrorMessage, name, _basePropertyName);
        }
    
    
        //Override IsValid
        protected override ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
        {
            //Get PropertyInfo Object
            var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName);
            var baseValue = (string)basePropertyInfo.GetValue(validationContext.ObjectInstance, null);
            var currentValue = (string)value;
    
    
            string firstLetterBaseValue = baseValue.Substring(0, 1);
            string firstLetterCurrentValue = currentValue.Substring(0, 1);
    
            //Comparision
            if (!string.Equals(firstLetterBaseValue, firstLetterCurrentValue))
            {
                var message = FormatErrorMessage(validationContext.DisplayName);
                return new ValidationResult(message);
            }
    
            //Default return - This means there were no validation error
            return null;
        }
    
    
        public IEnumerable<System.Web.Mvc.ModelClientValidationRule> GetClientValidationRules(System.Web.Mvc.ModelMetadata metadata, System.Web.Mvc.ControllerContext context)
        {
            var rule = new System.Web.Mvc.ModelClientValidationRule();
            rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
            rule.ValidationParameters.Add("other", _basePropertyName);
            rule.ValidationType = "greaterdate";
            yield return rule;
        }
    
    
    
    }
    

    }

    查看

    @model MyValidationTEST.Person
    
    @{
    ViewBag.Title = "Create";
    }
    
    <h2>Create</h2>
    
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">  </script>
    
    @*UnObtrusive*@
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    
    
    <script type="text/javascript">
    
    /*Register adapter - addSingleVal*/
    jQuery.validator.unobtrusive.adapters.addSingleVal("greaterdate", "other");
    
    
    /*Validation type names in unobtrusive client validation rules must consist of only lowercase letters*/
    
    /*Add Method*/
    jQuery.validator.addMethod("greaterdate",
                                        function (val, element, other) 
                                        {
    
                                            var modelPrefix = element.name.substr(0, element.name.lastIndexOf(".") + 1)
                                            var otherVal = $("[name=" + modelPrefix + other + "]").val();
    
                                            if (val && otherVal) 
                                            {
                                                var lastNameFirstLetter = val.substr(0, 1);
                                                var firstNameFirstLetter = otherVal.substr(0, 1);
    
                                                if (lastNameFirstLetter != firstNameFirstLetter) 
                                                {
                                                    return false;
                                                }
                                            }
                                            return true;
                                        });
    
    
    </script>
    
    
    @using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</legend>
    
        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
    
        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    
        <div class="editor-label">
            @Html.LabelFor(model => model.Age)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>
    
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
    }
    
    <div>
    @Html.ActionLink("Back to List", "Index")
    </div>
    

    控制器:

    using System.Web.Mvc;
    namespace MyValidationTEST.Controllers
    {
    public class RelativesController : Controller
    {
    
        // GET: /Relatives/
        public ActionResult Index()
        {
            return View();
        }
    
    
    
        // GET: /Relatives/Create
        public ActionResult Create()
        {
            Person person = new Person();
            return View(person);
        }
    
    
        // POST: /Relatives/Create
        [HttpPost]
        public ActionResult Create(Person relativeToAdd)
        {
            if (ModelState.IsValid)
            {
                return RedirectToAction("Index");
            }
            return View(relativeToAdd);
        }
    
        }
    
     }
    

    读:

    ASP.NET MVC3 - Custom validation attribute -> Client-side broken

1 个答案:

答案 0 :(得分:8)

  

我想将其更改为“anotherDefaultType”

之类的其他内容

ValidationType属性只能使用小写字母:

rule.ValidationType = "anotherdefaulttype";

然后调整客户端脚本以反映此修改:

jQuery.validator.unobtrusive.adapters.addSingleVal("anotherdefaulttype", "other");
jQuery.validator.addMethod("anotherdefaulttype", function (val, element, other) {
    ...
});