asp.net正则表达式验证器客户端脚本错误

Abh*_*tel 5 .net regex asp.net

我有以下正则表达式验证器来检测输入字符串是否包含HTML /脚本标记,如果是这样,则会导致更改错误:

<asp:TextBox ID="txt" runat="server" />
    <asp:RegularExpressionValidator 
        ControlToValidate="txt" 
        runat="server"
        ID="regexVal"
        EnableClientScript="true"  Display="Dynamic"
        ErrorMessage="Invalid Content" 
        Text="!" 
        ValidationExpression=">(?:(?<t>[^<]*))" />
Run Code Online (Sandbox Code Playgroud)

当我运行托管此标记的页面时,我收到一条scipt错误消息"正则表达式中的语法错误".但是,当我使用相同的正则表达式并使用System.Text.RegularExpressions中的Regex类运行它时,一切正常:如下所示:

Regex r = new Regex(">(?:(?<t>[^<]*))");
r.IsMatch(@"<b>This should cause a validation error</b>");
r.IsMatch("this is fine");
Run Code Online (Sandbox Code Playgroud)

我错过了什么

更新:错误似乎发生在WebResource.axd中的以下js函数中:

function RegularExpressionValidatorEvaluateIsValid(val) {
    var value = ValidatorGetValue(val.controltovalidate);
    if (ValidatorTrim(value).length == 0)
        return true;
    var rx = new RegExp(val.validationexpression); //this is the line causing the error
    var matches = rx.exec(value);
    return (matches != null && value == matches[0]);
}
Run Code Online (Sandbox Code Playgroud)

dar*_*iom 11

我认为问题是JavaScript不理解.NET的分组正则表达式语法.

当您设置EnableClientScripttrueon时,RegularExpressionValidatorASP.NET会在JavaScript中重新创建正则表达式,以便对您的控件启用客户端验证.在这种情况下,JavaScript不支持命名组(?<t>...)和非捕获组的语法(?:...).虽然这些功能在.NET中运行,但JavaScript正在努力解决它们.

来自MSDN上的RegularExpressionValidator控件(常规参考):

在客户端上,使用JScript正则表达式语法.在服务器上,使用Regex语法.由于JScript正则表达式语法是Regex语法的子集,因此建议您使用JScript正则表达式语法,以便在客户端和服务器上产生相同的结果.

有两种方法可以解决这个问题:

  1. 禁用客户端脚本生成并在服务器端使用正则表达式execue.您可以通过设置EnableClientScriptfalse.
  2. 修改正则表达式并删除非捕获组和命名组.如果需要在正则表达式中捕获,(...)语法应该在JavaScript和.NET中都能正常工作.然后,您可以使用序号引用访问捕获的值($1,$2,等).类似的东西>[^<]*应该按预期工作.请参阅MSDN上的分组构造.

我想指出其他几个问题:

  • 如果你想要做的就是检查是否存在开口尖括号,你原来的正则表达式似乎根本不需要捕获.它可以被重写为>[^<]*更简单,工作方式完全相同.它不会捕获原始字符串中的任何值,但由于您在ASP.NET验证控件中使用它,因此这无关紧要.
  • 您实施该方法的方式RegularExpressionValidator仅在匹配成功时才有效.在您的情况下,如果您的文本框包含类似的内容,则验证将通过>blah.我想你想让它以相反的方式工作.
  • 如果将正则表达式修改为>[^<]*,则正则表达式仍然无法正常工作.验证控件尝试匹配文本框中的所有文本.因此,如果我输入>blah文本框,它将匹配,但<b>blah</b>不会,因为正则表达式表示该字符串必须以a开头>.我建议在尝试.*>.*[^<]*之前尝试允许文本>.