MVC 5自定义验证属性未触发

时间:2016-04-05 14:12:09

标签: c# asp.net-mvc validation asp.net-mvc-5

所以我一直在这里撞墙。我按照教程写了这封信,我没有想到为什么这个自定义验证不起作用。它应该验证电话号码。

缩短到最后

自定义属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class CustomPhoneAttribute : DataTypeAttribute, IClientValidatable
{
    private static readonly string[] ddds = new[] { ... };

    private static Regex regex = new Regex(@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4}$", RegexOptions.Compiled);

    private const string DefaultErrorMessage = "{0} must be a phone number.";

    public CustomPhoneAttribute()
      : base(DataType.PhoneNumber)
    {
        ErrorMessage = DefaultErrorMessage;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name);
    }

    private bool ValidatePhone(string phone)
    {

        if (regex.Match(phone).Success)
        {
            var ddd = phone.Substring(1, 2);

            if (ddds.Contains(ddd))
            {
                var phoneParts = phone.Substring(5).Split('-');
            }

            // TODO: perform further evaluation base on
            // ddd, first digit and extra 9.
            // For now we only check the ddd exists.

            return true;
        }

        return false;
    }

    public override  bool IsValid(object value)
    {
        if (value == null)
        {
            return true;
        }

        return ValidatePhone((string)value);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule()
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "brphone"
        };

    }

型号:

{...}

[CustomRequired] // this works.
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone")]
[CustomPhone]
public string Phone { get; set; }

{...}

使用Javascript:

$.validator.addMethod("brphone",

function (value, element) {

    if (!this.optional(element)) {

        // perform validation.
        return true;
    }

    return true;
});

$.validator.unobtrusive.adapters.addBool("brphone");

查看:

@Html.TextBoxFor(m => m.Phone, new { @class = "form-control phonemask-client", placeholder = "(xx) xxxxx-xxxx" })

一切似乎都要检查,但服务器端和客户端验证都没有工作。

图示部分(可能来自微软的错误)

如果我从数据注释类中删除正则表达式对象,它就像一个魅力。现在,为什么会这样,我不知道!如果我附加一个调试器,当它到达正则表达式声明并且我单击跳过继续调试时,程序只返回到网页并且没有任何反应。

是否禁止在数据注释中使用正则表达式?

2 个答案:

答案 0 :(得分:1)

您在正则表达式中缺少括号,这会在实例化属性时导致错误。

// missing ')' between the {4} and $
private static Regex regex = new Regex(@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4})$", RegexOptions.Compiled); 

由于字段上的static关键字,我们在运行时看不到错误。

让我们假装你的属性看起来像这样:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class CustomPhoneAttribute : DataTypeAttribute
{
    public static string MyString = GetValue();

    public CustomPhoneAttribute()
        : base(DataType.PhoneNumber)
    {
    }

    private static string GetValue()
    {
        throw new Exception();
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return base.IsValid(value, validationContext);
    }
}

使用static关键字时,运行时需要在实例化类本身之前的某个时间点初始化类型级别值。但是,当发生这种情况时会导致崩溃,因为GetValue代码会抛出异常。当MVC查看数据注释的模型时,将发生该错误,并且它将依次忽略该属性(因为它无法实例化)。

通过删除static关键字,会导致在实例化注释时在构造函数中抛出错误,因此它首先在代码中抛出,调试器可以在其上中断。

答案 1 :(得分:0)

解决。 问题在于正则表达式。它错过了关闭&#34;)&#34;。可笑的是,我没有得到例外。

所以:

@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4}$"

变为

@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4})$"

要找出异常,我必须在另一个项目中实现注释。作为图书馆。 然后,我将dll添加到我当前的项目并尝试使用它。我有一个黄页说我的正则表达式错了。

这个异常应该来自我自己的代码,meh。