5

我有 ASP.NET MVC 网页,我使用 DataAnnotation 在客户端验证表单。其中一个视图类具有如下所示的属性:

[StringLength(100, MinimumLength = 3, ErrorMessage = "Länken måste vara mellan 3 och 100 tecken lång")]
[Display(Name = "Länk")]
[RegularExpression(@"^(http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?)?$", ErrorMessage="Länkgen är inte giltlig")]
        public string Url { get; set; }

在视图中,我将此代码用于属性:

@Html.LabelFor(c => c.Url, true)
@Html.TextBoxFor(c => c.Url, new { @class = "tb1", @Style = "width:400px;" })
@Html.ValidationMessageFor(model => model.Url)

粘贴这样的 URL 时:

http://95rockfm.com/best-voicemail-giving-play-by-play-of-car-accident/

网页将锁定,我无法在网页上执行任何操作。但是,如果我将其粘贴到:

http://95rockfm.com/best-voicemail-giving-play-by-play-of-car-accident

它工作得很好。

这些 javascript 文件包含在网页底部:

<script type="text/javascript" src="/Scripts/jquery.qtip.min.js"></script>
<script src="/Scripts/jquery-1.7.1.min.js"></script>
<script src="/Scripts/jquery-ui-1.8.20.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>

完全相同的问题在 IE 和 Chrome 中都会出现。然而,IE 会回来说脚本需要很长时间,并且需要一个按钮来停止脚本。但是当切换输入控件时,脚本将再次运行并查看网页。

我没有使用任何自定义的东西,所以为什么我会得到这个?

4

2 回答 2

5

.在正则表达式中匹配任何字符(事实上,这个句点与 URL 中域后面的斜杠匹配)。您需要对其进行转义或将其放入字符类中以匹配句点。像这样:

@"^(http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=])?)?$"

或者:

@"^(http(s)?://([\w-]+[.])+[\w-]+(/[\w- ./?%&=])?)?$"

如果您不这样做,并且该模式找不到匹配项,则您有一个嵌套重复,具有指数数量的可能组合。正如 nemesv 在评论中与您联系的那样,这会导致灾难性的回溯。但是,如果您匹配组内的文字句点,则整个组的每次重复都必须以句点结尾,因此没有指数数量的组合。

要了解“组合的指数数量”是什么意思,我将链接到我以前的两个答案(实际上是今天的一个):

还有一件事,为什么您的模式会失败(灾难性回溯主要是匹配失败的问题):在第一个斜杠之后只需要一个字符。您可能希望允许任意长的路径和查询字符串,因此在+该字符类中添加一个:

@"^(http(s)?://([\w-]+[.])+[\w-]+(/[\w- ./?%&=]+)?)?$"

但是,一般来说,为什么要重新发明轮子,而不是仅仅在谷歌上搜索已建立的 URL 正则表达式模式

于 2013-09-22T20:34:31.097 回答
2

MVC 已经使用 URL 验证UrlAttribute

[Url]
public string Url { get; set; }

如果您使用的是 MVC 4,它还将创建一个 HTML 5<input type="url">元素。

客户端验证将使用jQuery Validation 的 URL 规则,它仍然是一个正则表达式,但要好得多(例如,它支持更多的 Unicode 字符)。

于 2013-09-24T12:31:35.103 回答