2012-08-09 49 views
1

我有一個MVC3項目中的幾個視圖,允許用戶輸入Url到文本輸入並將其作爲數據保存在實體上。確定數據輸入是一個有效的URL

我們需要驗證輸入是一個有效形成的Url。

我首先使用http://dataannotationsextensions.org/[Url]註釋開始,但由於某種奇怪的原因,如果用戶輸入任何大寫字符,客戶端驗證將失敗。所以爲了緩解我添加了一個jQuery事件,強制輸入爲用戶鍵入的小寫字母。事實證明,這不是最佳的,因爲用戶可以粘貼Url縮短服務(如tinyUrl等)縮短的Url,並且這些大寫字符對於翻譯是必需的。

所以我去了,而不是用正則表達式:

[RegularExpression(@"^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\[email protected])?([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")] 

這工作正常允許大寫字符。但這並不完美。有了這個正則表達式,這些都被認爲是有效的:

  1. www.asp
  2. asp.net
  3. http://asp.net
  4. http://www.asp.net
  5. http://www.asp

正如你所看到的,其中的一些並不是真正有效的。

這些Url的最大問題是在顯示視圖中顯示Url時。如果URL文本沒有前置到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,但也是abbrevia例如:

asp.net 
www.asp.net 

而不必包括前置協議。

更新

這裏是使用註釋我的視圖模型我的網址野的http://dataannotationsextensions.org/

[Required] 
[StringLength(128)] 
[Url(false)] // false denotes whether the protocol is required or not 
public string URL { get; set; } 

所以定義你不覺得我的堅果,這裏是用截圖大寫而不是大寫。在IE8和Chrome進行測試,到目前爲止,我也得到了相同的結果

Screenshot

+0

這5個示例中的哪一個不是真正有效的?好吧,他們可能並不是所有的解決方案,但是如果你想測試一下,你可以取消正則表達式,只需要ping它們。 – Widor 2012-08-09 15:47:30

+0

1和5是完全無效的,因爲沒有辦法到達該地址,但5創建Url,只是不可通航。 2,3和4是有效的,但只有3和4(前綴爲http://是可導航的,沒有http://的任何內容都會創建一個不良的可導航Url,如上面的http://www.mydomain.com/所示控制器/動作/ www.asp' – 2012-08-09 15:50:01

回答

0

解決,2 DLL文件DataAnnotationsExtensions.dll和DataAnnotationsExtensions.ClientValidation.dll從http://dataannotationsextensions.org/,我用了版本1.0,並且不允許在[Url]註釋中大寫。我更新到1.1版本,因爲這是在網站上演示的版本,現在問題已解決。

使用[Url]現在將允許我強制執行http://如果我絕對必須以及允許大寫字符。

使用[Url(false)]將允許用戶不必輸入http://,我可以在代碼中加上它。

0

[Url]http://dataannotationsextensions.org/工作完全正常,我用大寫字母。但是,如果由於某種原因,你不想使用它,你可以抄襲的正則表達式,它使用:

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; } 
} 
+0

看到我上面的編輯,有截圖和模型定義 – 2012-08-09 16:01:42

+0

爲什麼你將false傳遞給Url構造函數?這與你需要強制執行協議的需求是矛盾的 – 2012-08-09 16:02:39

+0

這是測試兩種情況。我不希望強迫用戶輸入協議,除非我絕對必須。我們的大多數用戶將進入'www.mybankname.com'或'myschoolname.edu' – 2012-08-09 16:04:27

相關問題