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

C# MVC 5自定义验证属性未触发,c#,asp.net-mvc,validation,asp.net-mvc-5,C#,Asp.net Mvc,Validation,Asp.net Mvc 5,所以我一直把头撞在墙上。我严格按照教程进行操作,不知道为什么这个自定义验证不起作用。它应该验证电话号码 对于较短的,请转到结尾 自定义属性: [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class CustomPhoneAttribute : DataTypeAttribute, IClientValidatable { private static readonly s

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

对于较短的,请转到结尾

自定义属性:

[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; }

{...}
$.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" })
Javascript:

[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; }

{...}
$.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" })
查看:

[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; }

{...}
$.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" })
一切似乎都正常,但服务器端和客户端验证都不起作用

找到了其中的一部分(可能是微软的bug)

如果我从data annotation类中删除regex对象,它会像一个符咒一样工作。现在,为什么会这样,我不知道!如果我附加了一个调试器,当它点击regex声明时,我单击step over继续调试,程序只会返回到网页,什么也不会发生


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

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

{4}和之间缺少“')”$ 私有静态正则表达式Regex=newregex(@“^(\([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查看模型中的数据注释时,会出现该错误,而MVC反过来会忽略该属性(因为它无法实例化)

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

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

因此:

变成

@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4})$"
为了找出异常,我必须在另一个项目中实现注释。作为图书馆。 然后,我将dll添加到当前项目中并尝试使用它。我收到一张黄页说我的正则表达式错了


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

当你回答时,我正在键入我的答案。老兄,就是因为这个愚蠢的设计而损失了几个小时的工作。为什么我自己的代码中没有出现异常?顺便说一句,我确实尝试过删除静态,但它仍然没有为我抛出异常(使用MVC5)。我不得不尝试从另一个dll执行它以获得异常。我对编译时错误的看法是错误的,它总是在运行时出现。我将更新我的答案以更正此问题,并添加一个示例来帮助解释为什么我们在运行时没有看到静态字段的异常。如何调试该异常并查看是否存在错误?@batmaci RegEx或属性的实现中存在错误?