【问题标题】:MVC 5 custom validation attribute not triggered未触发 MVC 5 自定义验证属性
【发布时间】:2016-04-05 14:12:09
【问题描述】:

所以我一直在这里撞墙。我完全按照教程进行操作,但我不知道为什么这个自定义验证不起作用。它应该验证电话号码。

更短的请到最后

自定义属性:

[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" })

一切似乎都检查过了,服务器端和客户端验证仍然没有工作。

已确定部分内容(可能来自微软的错误)

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

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

【问题讨论】:

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


    【解决方案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 关键字,当注解被实例化时,您会在构造函数中引发错误,因此它会首先在您的代码中引发并且调试器可以中断它。

    【讨论】:

    • 当你回答时我正在输入我的答案。伙计,因为这个愚蠢的设计,刚刚失去了几个小时的工作。为什么我自己的代码没有出现异常?顺便说一句,我确实尝试删除静态,但它仍然没有为我抛出异常(使用 mvc 5)。我不得不尝试从另一个 dll 执行它以获取异常。
    • 我错了编译时错误,它总是在运行时。我将更新我的答案以纠正该问题并添加一个示例来帮助解释为什么我们在运行时没有看到静态字段的异常。
    • 你如何调试它并查看是否有错误?
    • @batmaci 正则表达式或属性实现中的错误?
    【解决方案2】:

    解决了。 问题出在正则表达式中。它缺少一个结束的“)”。可笑的是,我没有得到例外。

    所以:

    @"^(\([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 添加到我当前的项目中并尝试使用它。我得到一个黄页,说我的正则表达式错误。

    这个异常应该是我自己的代码抛出的,嗯。

    【讨论】:

      猜你喜欢
      • 2019-03-13
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多