title: Determining data input is a valid URL
body: <p>I have several views in an MVC3 project that allow a user to enter a Url into a text input and save it as data on an entity. </p>
  
  <p>We need to validate that the input is a validly formed Url.</p>
  
  <p>I first started with using the <code>[Url]</code> annotation from <a href="http://dataannotationsextensions.org/" rel="nofollow noreferrer">http://dataannotationsextensions.org/</a> but for some strange reason, the client-side validation fails if the user inputs any uppercase characters. So to alleviate that I added a jQuery event that forces the input to lowercase as the user types. Turns out this isn't optimal either because the user can paste in a Url that has been shortened by a Url shortening service such as tinyUrl, etc. and those uppercase characters are necessary for the translation.</p>
  
  <p>So I went instead with a regular expression:</p>
  
  <pre><code>[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+)?(&amp;\w+=\w+)*)?", ErrorMessage = "Please enter a valid Url")]
  </code></pre>
  
  <p>This works fine for allowing uppercase characters. But it's not perfect. With this Regex these are all considered valid:</p>
  
  <ol>
  <li>www.asp</li>
  <li>asp.net</li>
  <li><a href="http://asp.net" rel="nofollow noreferrer">http://asp.net</a></li>
  <li><a href="http://www.asp.net" rel="nofollow noreferrer">http://www.asp.net</a></li>
  <li><a href="http://www.asp" rel="nofollow noreferrer">http://www.asp</a></li>
  </ol>
  
  <p>As you can see, some of these aren't truly valid.</p>
  
  <p>The biggest problem with these Urls is when displaying the Url back in a Display View. If the Url text does not have the <code>http://</code> prepended to the Url then the link that is created in the View ends up looking like this:</p>
  
  <pre><code>http://www.mydomain.com/controller/action/www.asp 
  </code></pre>
  
  <p>or </p>
  
  <pre><code>http://www.mydomain.com/controller/action/asp.net
  </code></pre>
  
  <p>which are both invalid obviously. </p>
  
  <p>For example, this bit of Razor code will create a link like the two above if the Url does not have <code>http://</code> prepended</p>
  
  <pre><code>....
  &lt;a href="@item.Link" target="blank"&gt;@item.LinkName&lt;/a&gt;
  ...
  </code></pre>
  
  <p>But if the entered Url has <code>http://</code> prepended the Url generated in the display view actually is a real Url such as</p>
  
  <pre><code>http://www.asp.net
  http://asp.net
  http://www.asp - this is actually an invalid address as well but it renders out correctly.
  </code></pre>
  
  <p>Surely, showing a Url that was saved into a db and then shown on a View isn't as difficult as this and also allowing a user to save a well formed Url but also abbreviating it such as:</p>
  
  <pre><code>asp.net
  www.asp.net
  </code></pre>
  
  <p>without having to include the prepended protocol.</p>
  
  <p><strong>Update</strong></p>
  
  <p>Here is the definition of my Url field in my ViewModel using the annotation from <a href="http://dataannotationsextensions.org/" rel="nofollow noreferrer">http://dataannotationsextensions.org/</a> </p>
  
  <pre><code>[Required]
  [StringLength(128)]
  [Url(false)] // false denotes whether the protocol is required or not
  public string URL { get; set; }
  </code></pre>
  
  <p>So you don't think I'm nuts, here is a screenshot using uppercase and no uppercase. Tested in IE8 and Chrome so far and I get the same results</p>
  
  <p><img src="https://i.stack.imgur.com/kQ15o.png" alt="Screenshot"></p>