【问题标题】:How can I set a RegularExpression data annotation's regular expression argument at runtime?如何在运行时设置正则表达式数据注释的正则表达式参数?
【发布时间】:2011-12-08 12:29:52
【问题描述】:

我们管理着几个 ASP.NET MVC 客户端网站,它们都使用如下数据注释来验证客户电子邮件地址(为了便于阅读,我没有在此处包含正则表达式):

[Required(ErrorMessage="Email is required")]
[RegularExpression(@"MYREGEX", ErrorMessage = "Email address is not valid")]
public string Email { get; set; }

我想做的是集中这个正则表达式,这样如果我们对其进行更改,所有站点都会立即获取它,而我们不必在每个站点中手动更改它。

问题是数据注释的正则表达式参数必须是一个常量,所以我无法分配我在运行时从配置文件或数据库中检索到的值(这是我的第一个想法)。

任何人都可以帮助我解决这个问题 - 或者如果失败了,另一种方法可以实现相同的目标吗?或者这是否只需要我们编写一个专门的自定义验证属性来接受非常量值?

【问题讨论】:

标签: regex asp.net-mvc-3 validation dynamic data-annotations


【解决方案1】:

最简单的方法是编写一个继承自RegularExpressionAttribute 的自定义ValidationAttribute,例如:

public class EmailAttribute : RegularExpressionAttribute
    {
        public EmailAttribute()
            : base(GetRegex())
        { }

        private static string GetRegex()
        {
            // TODO: Go off and get your RegEx here
            return @"^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$";
        }
    }

这样,您仍然可以使用内置的正则表达式验证,但您可以对其进行自定义。您只需像这样使用它:

[Email(ErrorMessage = "Please use a valid email address")]

最后,为了让客户端验证正常工作,您只需在 Global.asax 内的 Application_Start 方法中添加以下内容,以告诉 MVC 对该验证器使用正常的正则表达式验证:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter));

【讨论】:

  • 我接受这个,因为它是一个简单、完整的解决方案,解释得很好。谢谢!
  • 谢谢马克,不用担心,很高兴它有帮助!
  • 这已经过去了一段时间,但有人能解释一下他们是如何从资源文件中获取正则表达式的吗?我可以在我的模型中获得预期的语言(例如,对于错误消息),但在上面使用时,我总是从扩展名中获得默认 .resx 文件的正则表达式。有什么想法吗?
  • 嗨 Alan,请参阅 msdn.microsoft.com/en-us/library/ms227982(v=vs.100).aspx,它解释了如何以编程方式获取资源值 - 您可以在 GetRegex 方法中使用 GetGlobalResourceObject 来访问本地化的正则表达式。或者,如果您将资源公开(参见holyhoehle.wordpress.com/2010/02/20/…),那么您可以访问Resource.Strings.SomeRegex 等。
  • 谢谢伊恩。在我的 GetRegex 方法中,我将 resx 文件中的值作为参数传递,然后返回如下表达式:return Resources.FormValidation.ResourceManager.GetString(value); 它大部分都在工作,但我总是在我的默认 resx 文件中获取值,而不是与一种有名的文化。我在这里有一个悬而未决的问题,提供更多信息(也许给你 50 分!):stackoverflow.com/questions/21735918/…
【解决方案2】:

Checkout ScotGu's [Email] attribute(第 4 步:创建自定义 [Email] 验证属性)。

【讨论】:

    【解决方案3】:

    您真的想将正则表达式放在数据库/配置文件中,还是只想集中它们?如果你只是想把正则表达式放在一起,你可以定义和使用像

    这样的常量
    public class ValidationRegularExpressions {
        public const string Regex1 = "...";
        public const string Regex2 = "...";
    }
    

    也许您想管理外部文件中的正则表达式,您可以在为生产构建时编写一个 MSBuild 任务来进行替换。

    如果您真的想在运行时更改验证正则表达式,请定义您自己的 ValidationAttribute,例如

    [RegexByKey("MyKey", ErrorMessage = "Email address is not valid")]
    public string Email { get; set; }
    

    只需要写一段代码:

    public class RegexByKeyAttribute : ValidationAttribute {
        public RegexByKey(string key) {
            ...
        }
    
        // override some methods
        public override bool IsValid(object value) {
            ...
        }
    }
    

    甚至只是:

    public class RegexByKeyAttribute : RegularExpressionAttribute {
        public RegexByKey(string key) : base(LoadRegex(key)) { }
    
        // Be careful to cache the regex is this operation is expensive.
        private static string LoadRegex(string key) { ... }
    }
    

    希望对你有帮助:http://msdn.microsoft.com/en-us/library/cc668224.aspx

    【讨论】:

      【解决方案4】:

      为什么不直接编写自己的 ValidationAttribute?

      http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute.aspx

      然后您可以配置该东西以从注册表设置中提取正则表达式...配置文件...数据库...等...等..

      How to: Customize Data Field Validation in the Data Model Using Custom

      【讨论】:

        猜你喜欢
        • 2014-07-26
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-07-08
        • 2014-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多