26

クライアント側の検証に使用する文字列があります。

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")]属性で使用します。

/iJavascript 正規表現のフラグが大文字と小文字を区別しないようにするために使用されていることは知っていますが、正規表現の最後に追加するだけです (つまり@"^....$/i"、機能していません - 入力内容 (有効かどうかに関係なく) 正規表現の検証は完全に失敗します)。 )。

私は何が欠けていますか?

4

3 に答える 3

41

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.NETMVC3カスタムバリデーターを使用した控えめなJavascript検証

于 2013-02-19T16:21:59.497 に答える
18

C# では、いくつかの正規表現オプションをインライン化できます。大文字と小文字を区別しないオプションを指定するに(?i)は、パターンの先頭に追加します。ただし、これが によってどのように処理されるかRegularExpressionAttribute、クライアント側の翻訳を処理するかどうかはわかりません。ASP.NET での経験から、私はRegularExpressionValidatorそれを疑っています。正規表現は、両方のエンジンで機能するのに十分なバニラでなければなりません。

いずれにせよ、それが有効であれば、次のようになります。

@"^(?i)(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([A-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$"
于 2010-11-18T20:03:38.227 に答える
7
private const String regex = @"^(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([a-zA-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+$";
于 2010-11-18T19:53:46.467 に答える