我在MVC3项目中有几个视图,允许用户将Url输入到文本输入中并将其作为数据保存在实体上。
我们需要验证输入是否是有效形成的URL。
我首先使用http://dataannotationsextensions.org/中的[Url]
注释开始,但由于某些奇怪的原因,如果用户输入任何大写字符,则客户端验证将失败。因此,为了减轻这种情况,我添加了一个jQuery事件,在用户输入时强制输入为小写。事实证明这不是最佳选择,因为用户可以粘贴已被缩短了Url缩短服务(如tinyUrl等)的Url,并且这些大写字符是翻译所必需的。
所以我改为使用正则表达式:
[RegularExpression(@"^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\w+@)?([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)(\w+\.[\w]{3,4})?((\?\w+=\w+)?(&\w+=\w+)*)?", ErrorMessage = "Please enter a valid Url")]
这适用于允许大写字符。但它并不完美。有了这个正则表达式,这些都被认为是有效的:
正如您所看到的,其中一些并非真正有效。
这些网址的最大问题是在显示视图中显示网址时。如果网址文字没有在网址前加http://
,那么在视图中创建的链接最终会如下所示:
http://www.mydomain.com/controller/action/www.asp
或
http://www.mydomain.com/controller/action/asp.net
显然都是无效的。
例如,如果Url没有http://
前置
....
<a href="@item.Link" target="blank">@item.LinkName</a>
...
但如果输入的网址前面有http://
,则在显示视图中生成的网址实际上是一个真实的网址,例如
http://www.asp.net
http://asp.net
http://www.asp - this is actually an invalid address as well but it renders out correctly.
当然,显示保存到数据库然后在视图上显示的Url并不像这样困难,并且允许用户保存格式正确的Url,但也可以缩写它,例如:
asp.net
www.asp.net
无需包含前置协议。
更新
以下是使用http://dataannotationsextensions.org/
中的注释在我的ViewModel中定义我的Url字段[Required]
[StringLength(128)]
[Url(false)] // false denotes whether the protocol is required or not
public string URL { get; set; }
所以你不认为我疯了,这是一个使用大写但没有大写的截图。到目前为止在IE8和Chrome中测试过,我得到了相同的结果
答案 0 :(得分:0)
[Url]
使用大写字母对我来说非常合适。但如果由于某种原因你不想使用它,你可能会剽窃它使用的正则表达式:
public class MyViewModel
{
[RegularExpression(@"^(https?|ftp):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$")]
public string Url { get; set; }
}
答案 1 :(得分:0)
解决了,我使用的http://dataannotationsextensions.org/中的2个DLL DataAnnotationsExtensions.dll和DataAnnotationsExtensions.ClientValidation.dll是版本1.0,并且不允许在[Url]
注释中使用大写。我更新到版本1.1,因为这是在网站上演示的版本,现在问题已解决。
使用[Url]
现在允许我强制执行http://
,如果我绝对必须允许大写字符。
使用[Url(false)]
将允许用户无需输入http://
,我可以将其添加到代码中。