ASP.NET MVC3:ValidationType ModelClientValidationRule

发布于 2025-01-07 05:34:48 字数 6765 浏览 3 评论 0原文

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

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

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

  1. 这是什么原因呢?
  2. 有哪些可用的验证类型?
  3. 在这种情况下更改 ValidationType 的建议方法是什么

代码:

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 - 自定义验证属性->客户端损坏

I just created a sample MVC3 application to learn validation. It is using DataAnnotations. I have created a custom ValidationAttribute named CustomStartLetterMatch. It is implementing “System.Web.Mvc.IClientValidatable”. I have corresponding client-side code written with unobtrusive jQuery. This is working as expected.

About the custom validator: It compares the first name input and last name input. It throws error if first character of both of them are not same.

As I said, the application is working fine. But when I looked at the rule.ValidationType = "greaterdate"; I got confused. I wanted to change it to something else like “anotherDefaultType”. When I am changing it, it fails with jQuery error.

  1. What is the reason for this?
  2. What are the available ValidationTypes?
  3. What is the suggested approach to change the ValidationType in this scenari

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;
    }



}

}

VIEW

@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>

CONTROLLER:

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);
    }

    }

 }

READING:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2025-01-14 05:34:48

我想将其更改为其他内容,例如“anotherDefaultType”

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

rule.ValidationType = "anotherdefaulttype";

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

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

I wanted to change it to something else like "anotherDefaultType"

You can use only lowercase letters for the ValidationType property:

rule.ValidationType = "anotherdefaulttype";

and then adapt your client script to reflect this modification:

jQuery.validator.unobtrusive.adapters.addSingleVal("anotherdefaulttype", "other");
jQuery.validator.addMethod("anotherdefaulttype", function (val, element, other) {
    ...
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文