我注意到,在创建自定义验证属性时,我的验证仅在本机MVC数据注释触发后触发.有什么办法可以“同时”解雇吗?
为了表明我的意思,假装我有这样的形式:
FirstName: <FirstName TextBox> LastName: <LastName TextBox> Zip: <Zip TextBox>
所以我对所有3都有一个[required]注释,但另外,对于Zip属性,我有一个自定义属性.如果用户没有输入名字或姓氏,但是输入了无效的Zip(我的属性应该验证这一点),那么所有三个都应该有一条错误消息 – 但是没有. firstName和lastName只有一个错误.
这是代码:
Person.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; // My validator using MvcApplication3.Extensions.Validation; namespace MvcApplication3.Models { public class Person { [required(ErrorMessage="Field required!")] public string firstName{get;set;} [required(ErrorMessage="Field required!")] public string lastName { get; set; } [Zip(ErrorMessage="You gotta put in a valid zip code")] [required(ErrorMessage="Field required!")] public string zipCode { get; set; } } }
控制器:
[HttpPost] public ActionResult Index(FormCollection form,Person person) { return View(person); }
视图:
@model MvcApplication3.Models.Person @{ ViewBag.Title = "Person"; Layout = "~/Views/Shared/_Layout.cshtml"; } <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> <h2> Testing Form: @Model.firstName </h2> <hr /> @{Html.EnableClientValidation();} @using (Html.BeginForm()) { @Html.LabelFor(model => model.firstName) @Html.TextBoxFor(model => model.firstName) @Html.ValidationMessageFor(model=>model.firstName) <br /><br /> @Html.LabelFor(model => model.lastName) @Html.TextBoxFor(model => model.lastName) @Html.ValidationMessageFor(model=>model.lastName) <br /><br /> @Html.LabelFor(model => model.zipCode) @Html.TextBoxFor(model => model.zipCode) @Html.ValidationMessageFor(model=>model.zipCode) <br /><br /> <input type="submit" value="Submit" /> }
Zip Validator(Zip.cs):
public class ZipAttribute : ValidationAttribute { public override bool IsValid(object value) { bool foundMatch = false; try { foundMatch = Regex.IsMatch(value.ToString(),"\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z"); } catch (ArgumentException ex) { // Syntax error in the regular expression } return foundMatch; } }
此外,我知道我可以使用Regexp数据注释来做到这一点,但我希望将来推出自己的自定义验证器.
谢谢!
解决方法
您需要添加将在客户端运行的验证的Javascript版本(或禁用客户端验证,但这有点不对劲).
http://thepursuitofalife.com/asp-net-mvc-3-unobtrusive-javascript-validation-with-custom-validators/
这显示了C#代码(包括设置将进行客户端验证的javascript函数名称)以及javascript“validemail”例程.
public class ValidEmailAttribute : ValidationAttribute,IClientValidatable { // ... public IEnumerable GetClientValidationRules(ModelMetadata Metadata,ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = FormatErrorMessage(Metadata.DisplayName),ValidationType = "validemail" }; } }
和JS:
$(function() { jQuery.validator.addMethod("validemail",function (value,element,param) { var emailPattern = /^[a-zA-Z0-9._-]+@@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; return emailPattern.test(value); }); jQuery.validator.unobtrusive.adapters.addBool("validemail"); });