RegularExpressionAttribute - как сделать так, чтобы он не учитывал регистр для проверки на стороне клиента? - PullRequest
21 голосов
/ 18 ноября 2010

У меня есть строка, которую я использую для проверки на стороне клиента:

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")].

Я знаю, что флаг /i для регулярного выражения Javascript используется для того, чтобы сделать его нечувствительным к регистру, но просто привязывает его к концу моего регулярного выражения (т.е. @"^....$/i" не работает - проверка правильности регулярного выражения завершается неудачно независимо от того, что введено (действует или нет).

Чего мне не хватает?

Ответы [ 3 ]

35 голосов
/ 19 февраля 2013

Я создал этот атрибут, который позволяет вам указывать 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);

Эта статья Энтони Стивенса помогла мне заставить это работать: Ненавязчивая проверка ASP.NET MVC 3 с помощью пользовательских средств проверки

16 голосов
/ 18 ноября 2010

В C # вы можете встроить некоторые параметры регулярных выражений.Чтобы указать опцию игнорирования регистра, вы должны добавить (?i) в начало вашего шаблона.Тем не менее, я не уверен, как это будет обрабатываться RegularExpressionAttribute и обрабатывает ли он перевод на стороне клиента.Из моего опыта работы с ASP.NET RegularExpressionValidator я сомневаюсь в этом;регулярного выражения должно быть достаточно ваниль , чтобы работать на обоих двигателях.

В любом случае, если оно действительно, оно будет выглядеть так:

7 голосов
/ 18 ноября 2010
private const String regex = @"^(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([a-zA-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$";
...