MVC3 和自定义客户端验证消息

MVC3 and custom client-side validation messages

提问人:doogdeb 提问时间:12/15/2011 最后编辑:doogdeb 更新时间:12/15/2011 访问量:821

问:

我的页面设置了不显眼的客户端验证。错误消息是从我们的数据库返回的。对于其中一条验证消息,我需要添加参数,以便可以使用特定值对其进行格式化。这在服务器端工作正常,但是在首次设置 GetClientValidationRules 方法时,我显然无法访问其中一些值。因此,看起来我将不得不在我的客户端代码中构建错误消息,但我不知道如何做到这一点,因为您只需在 jQuery.validator.addMethod 中返回 true 或 false。

因此,我基本上需要做的是将 ErrorMessage 设置为字符串。在 GetClientValidationRules 方法中为空,然后在执行验证的 clinet 端代码中能够返回我想要的任何消息。

下面是在 MVC 3 中连接的客户端代码。

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
                       {
                           ValidationType = "maximumdatecoverrequired",
                           ErrorMessage = string.Empty,
                       };

        rule.ValidationParameters.Add("maxdate", DateTime.Now.AddDays(Settings.Default.MaximumDateCoverRequiredDaysInFuture).ToString("yyyy/MM/dd"));

        return new[] { rule };
    }

这是我的客户端代码,用于针对此特定属性进行验证。

    jQuery.validator.addMethod("maximumdatecoverrequired", function (value, element,  params) {
        var maxDate = new Date(params["maxdate"]);
        var day = maxDate.getDate();
        var month = maxDate.getMonth() + 1;
        var year = maxDate.getFullYear();

        var dateCoverRequired = new Date(value).toString('yyyy/MM/dd');
        maxDate = maxDate.toString('yyyy/MM/dd');

        if (value > maxDate) {
            $("input#DateCoverRequired_Day").val(day);
            $("select#DateCoverRequired_Month").val(month);
            $("input#DateCoverRequired_Year").val(year);
            return false;
        }

        return true;
    });

如何在客户端代码中返回自定义消息?

asp.net-mvc-3 unobtrusive-javascript 客户端验证

评论

1赞 gdoron 12/15/2011
您要验证什么?缺少太多细节
0赞 doogdeb 12/15/2011
gdoron - 我已经用我想要完成的任务更新了我的问题。
0赞 Darin Dimitrov 12/15/2011
@doogdeb,再次更新它,这次不要忘记包含您的代码。

答:

1赞 Tom Chantler 12/15/2011 #1

让我举个例子来说明如何做到这一点。我将选择的示例是注册一个新用户并检查其名称。

我们要做的是允许用户选择一个用户名,如果它已经存在于数据库中,我们不会让他们拥有它,并会提出建议。

为此,我们将使用远程验证,它指向控制器中的 ActionMethod。

寄存器模型

public class RegisterModel
    {
        //This is the one I'm giving you the code for...
        [Required]
        [RegularExpression(@"(\S)+", ErrorMessage = "Username cannot contain spaces.")]
        [Remote("CheckUserName", HttpMethod="POST")]
        [Display(Name = "Username")]
        public string UserName { get; set; }

        // You can do this one yourself :-)
        [Required]
        [Remote("CheckEmailAddress", ErrorMessage="{0} already has an account, please enter a different email address.", HttpMethod="POST")]
        [DataAnnotationsExtensions.Email(ErrorMessage="{0} is not a valid email address.")]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [ValidatePasswordLength]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }

ActionMethod(模型引用的 Remote 方法)

[HttpPost]
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult CheckUserName(string userName, Guid? userId = null)
{
    if (userName != null || userName.Length > 2)
    {
        var users = Membership.FindUsersByName(userName);
        if (users.Count == 0)
        {
                return Json(true);
        }
        else
        {
            if ((users[userName].ProviderUserKey as Guid?) == userId)
            {
                return Json(true);
            }
            else
            {
                string suggestedUID = String.Format(CultureInfo.InvariantCulture, "{0} is not available.", userName);
                // Maybe this is a bit feeble, but it will loop around (inefficiently) and suggest a new username with a number on the end. EG Tom is not available. Try Tom37
                for (int i = 1; i < 100; i++)
                {
                    string altCandidate = userName + i.ToString();
                    if (Membership.FindUsersByName(altCandidate).Count == 0)
                    {
                        suggestedUID = String.Format(CultureInfo.InvariantCulture, "{0} is not available. Try {1}.", userName, altCandidate);
                        break;
                    }
                }
                // This is the important bit. I am returning a suggested UserName
                return Json(suggestedUID, JsonRequestBehavior.AllowGet);
            }
        }
    }
    else
    {
        return Json(true);
    }
}

我认为这很酷,因为正则表达式确保没有空格,然后(如果可以的话)将其提交到检查数据库的远程方法。