【发布时间】:2012-08-06 21:27:14
【问题描述】:
我在 MVC3 项目中有几个视图,允许用户在文本输入中输入 Url 并将其保存为实体上的数据。
我们需要验证输入是一个有效格式的 Url。
我首先使用http://dataannotationsextensions.org/ 中的[Url] 注释,但由于某些奇怪的原因,如果用户输入任何大写字符,客户端验证将失败。因此,为了缓解这种情况,我添加了一个 jQuery 事件,该事件在用户键入时强制输入为小写。事实证明这也不是最佳选择,因为用户可以粘贴已被 tinyUrl 等 Url 缩短服务缩短的 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")]
这适用于允许大写字符。但这并不完美。使用这个正则表达式,这些都被认为是有效的:
- www.asp
- asp.net
- http://asp.net
- http://www.asp.net
- http://www.asp
如您所见,其中一些并不是真正有效的。
这些 Url 的最大问题是在 Display View 中显示 Url 时。如果 Url 文本没有在 Url 前添加 http://,则在 View 中创建的链接最终看起来像这样:
http://www.mydomain.com/controller/action/www.asp
或
http://www.mydomain.com/controller/action/asp.net
这两个显然都是无效的。
例如,如果 Url 没有 http:// 前缀,那么这部分 Razor 代码将创建一个类似上述两个的链接
....
<a href="@item.Link" target="blank">@item.LinkName</a>
...
但是如果输入的Url前面有http://,那么显示视图中生成的Url实际上是一个真实的Url比如
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 中测试,我得到了相同的结果
【问题讨论】:
-
这 5 个例子中哪一个不是真正有效的?好的,它们可能不是全部 resolve,但如果你想测试你可以取消 Regex 并直接 ping 它们。
-
1 和 5 完全无效,因为无法到达该地址,尽管 5 创建了一个 Url,但无法导航。 2、3 和 4 是有效的,但只有 3 和 4(带有前缀的 http:// 是可导航的,没有 http:// 的任何内容都会创建一个错误的可导航 URL,如上所示
http://www.mydomain.com/controller/action/www.asp
标签: asp.net-mvc-3 url razor