ASP.NET MVC3:ValidationType ModelClientValidationRule
Posted
技术标签:
【中文标题】ASP.NET MVC3:ValidationType ModelClientValidationRule【英文标题】:ASP.NET MVC3: ValidationType ModelClientValidationRule 【发布时间】:2012-03-10 02:56:54 【问题描述】:我刚刚创建了一个示例 MVC3 应用程序来学习验证。它正在使用 DataAnnotations。我创建了一个名为 CustomStartLetterMatch 的 自定义 ValidationAttribute。它正在实现“System.Web.Mvc.IClientValidatable”。我有用不显眼的 jQuery 编写的相应客户端代码。这按预期工作。
关于自定义验证器:它比较名字输入和姓氏输入。如果它们的第一个字符不相同,则会引发错误。
正如我所说,应用程序运行良好。但是当我看到rule.ValidationType = "greaterdate";
时,我感到很困惑。我想把它改成“anotherDefaultType”之类的东西。当我更改它时,它会因 jQuery 错误而失败。
-
这是什么原因?
有哪些可用的 ValidationType?
在此场景中更改 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 - Custom validation attribute -> Client-side broken
【问题讨论】:
您是更改了rule.ValidationType = "greaterdate";
还是更改了javascript 代码以匹配它?
我在三个地方改了。 1) rule.ValidationType = "greaterdate" 2) 在 Javascript 中注册适配器。 3)在javascript中的add方法中
我也添加了控制器代码,你可以自己试一试看看错误。
【参考方案1】:
我想把它改成“anotherDefaultType”之类的东西
ValidationType 属性只能使用小写字母:
rule.ValidationType = "anotherdefaulttype";
然后调整您的客户端脚本以反映此修改:
jQuery.validator.unobtrusive.adapters.addSingleVal("anotherdefaulttype", "other");
jQuery.validator.addMethod("anotherdefaulttype", function (val, element, other)
...
);
【讨论】:
以上是关于ASP.NET MVC3:ValidationType ModelClientValidationRule的主要内容,如果未能解决你的问题,请参考以下文章