【问题标题】:RegularExpressionAttribute - How to make it not case sensitive for client side validation?RegularExpressionAttribute - 如何使其对客户端验证不区分大小写?
【发布时间】:2011-05-12 06:07:51
【问题描述】:

我有一个用于客户端验证的字符串:

private const String regex = @"^(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([A-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$";

我在[RegularExpression(regex, ErrorMessage = "invalid")] 属性中使用了这个字符串。

我知道 Javascript 正则表达式的 /i 标志用于使其不区分大小写,但只是将它附加到我的正则表达式的末尾(即 @"^....$/i" 不起作用 - 正则表达式验证完全失败,无论输入什么(有效与否)。

我错过了什么?

【问题讨论】:

  • 问题在于 .NET 和 JS 使用不同风格的 Regex,所以如果我们希望相同的模式在客户端和服务器上通用,我们必须使用在 JS 和 C# 中安全的正则表达式语法。或者,像Jeremy's solution below 这样的方法允许我们通过在服务器和客户端上分支验证逻辑来​​丰富地组合和控制两种语言的修饰符

标签: regex asp.net-mvc-2 client-side-validation


【解决方案1】:
private const String regex = @"^(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([a-zA-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$";

【讨论】:

  • 啊!当然!很好的答案 - 但是,我必须问:有没有办法使用不区分大小写的标志?
  • Regex re = new Regex(@"^(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([ a-zA-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$", RegexOptions .忽略大小写); // 这是c#代码。
  • 问题与 RegularExpressionAttribute 有关,您必须只传递字符串。所以你不能使用带有属性的 Regex 类
【解决方案2】:

我创建了这个属性,它允许您指定 RegexOptions。编辑:它还集成了不显眼的验证。客户端只会遵守 RegexOptions.Multiline 和 RegexOptions.IgnoreCase,因为这是 JavaScript 支持的。

[RegularExpressionWithOptions(@".+@example\.com", RegexOptions = RegexOptions.IgnoreCase)]

C#

public class RegularExpressionWithOptionsAttribute : RegularExpressionAttribute, IClientValidatable
{
    public RegularExpressionWithOptionsAttribute(string pattern) : base(pattern) { }

    public RegexOptions RegexOptions { get; set; }

    public override bool IsValid(object value)
    {
        if (string.IsNullOrEmpty(value as string))
            return true;

        return Regex.IsMatch(value as string, "^" + Pattern + "$", RegexOptions);
    }

    public IEnumerable<System.Web.Mvc.ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.DisplayName),
            ValidationType = "regexwithoptions"
        };

        rule.ValidationParameters["pattern"] = Pattern;

        string flags = "";
        if ((RegexOptions & RegexOptions.Multiline) == RegexOptions.Multiline)
            flags += "m";
        if ((RegexOptions & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase)
            flags += "i";
        rule.ValidationParameters["flags"] = flags;

        yield return rule;
    }
}

JavaScript

(function ($) {

    $.validator.unobtrusive.adapters.add("regexwithoptions", ["pattern", "flags"], function (options) {
        options.messages['regexwithoptions'] = options.message;
        options.rules['regexwithoptions'] = options.params;
    });

    $.validator.addMethod("regexwithoptions", function (value, element, params) {
        var match;
        if (this.optional(element)) {
            return true;
        }

        var reg = new RegExp(params.pattern, params.flags);
        match = reg.exec(value);
        return (match && (match.index === 0) && (match[0].length === value.length));
    });

})(jQuery);

Anthony Stevens 的这篇文章帮助我完成了这项工作:ASP.NET MVC 3 Unobtrusive Javascript Validation With Custom Validators

【讨论】:

  • 我没有测试过您的解决方案,但我知道一般方法有效,因为它在这里解决了类似的问题:stackoverflow.com/questions/5937174/…
  • 很棒的解决方案!我试图通过将输出模式包装在/pattern/flag literal syntax 中来清理和利用开箱即用的正则表达式验证器,但是该值被传递到不会解析属性的``new RegExp(params)` 构造函数语法中,因此该方法是正确的一个写客户端标志来处理我们自己
【解决方案3】:

在 C# 中,您可以内联一些正则表达式选项。要指定忽略大小写的选项,您可以将(?i) 添加到模式的开头。但是,我不确定RegularExpressionAttribute 将如何处理它以及它是否处理客户端的翻译。根据我对 ASP.NET 的RegularExpressionValidator 的经验,我对此表示怀疑;正则表达式应该 vanilla 足以适用于两个引擎。

无论如何,如果它是有效的,它应该是这样的:

@"^(?i)(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([A-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多