views:

335

answers:

4

Is there a method to validate URLs in .Net (or ASP.Net, or ASP.Net MVC)?

A: 

You can create a new Uri-object, if an exception is thrown, the url is malformed.

public static bool IsValidUri(String uri)
{
        try
        {
            new Uri(uri);
            return true;
        }
        catch (UriFormatException ex)
        {
            return false;
        }
    }
alexn
In the try block you'd want to return true...
great_llama
Of course. Late fridays...
alexn
+1  A: 
static bool IsValidUri(string urlString) {
   try {
      new Uri(urlString);
      return true;
   } catch {
      return false;
   }
}
Mehrdad Afshari
See comment regarding performance on divo's answer
Nathan Koop
+1  A: 

A faster way (probably) than using try/catch functionality would be to use Regex. If you had to validate 1000s of URLs catching the exception multiple times would be slow.

Here's a link to sample Regex- use Google to find more.

RichardOD
somehow i doubt that. regexes, even compiled are not especially fast. even if you could ever write one that was accurate.
Kris
This would be faster, but a lot harder to get right.
Joel Mueller
Kris- perhaps you don't understand how expensive throw exceptions can be- they are very slow if done in a big loop.
RichardOD
RichardOD - the sample regex you listed works for some URL's, but fails on the following 100% valid URL. Like I said, harder to get right. http://msdn.microsoft.com/en-us/library/zc5dc32d(VS.85).aspx
Joel Mueller
I guess if performance was a concern you could use Regex as the first method. If the Regex fails then switch to Uri.TryCreate. When I use Regex I usually write a bunch of unit tests to check the fringe cases.
RichardOD
+13  A: 

You can use the Uri.TryCreate to validate an URL:

public bool IsValidUri(string uri)
{
    Uri validatedUri;
    return Uri.TryCreate(uri, UriKind.RelativeOrAbsolute, out validatedUri);
}

The comments suggest that TryCreate just moves the exception handling one level down. However, I checked the source code and found that this is not the case. There is no try/catch inside TryCreate, it uses a custom parser which should not throw.

0xA3
This is better than the try/catch implementations suggested.
RichardOD
In case you're on 2.0+, of course...
Mehrdad Afshari
Although it's just burying the try/catch one more level down, where you don't have to see it.
great_llama
great-llama, that's true, but it is easier to read the code when using this syntax.
RichardOD
Nathan Koop
@Nathan Koop: This method is not available in .NET < 2.0. If you're using .NET 2.0+ you should prefer this method. If performance is a concern, you should be using Regex since Uri.TryCreate also does the check by catching the exception (unlike Int32.TryParse). I doubt it's 8000X faster, however!
Mehrdad Afshari
Nathan Koop
There is no try/catch inside TryCreate, but there is inside CreateHelper, which is called internally by TryCreate. So great_llama was correct, except the try/catch is moved two levels down, and some extra checks are done before the try/catch, so TryCreate may not always hit the try/catch block in all circumstances.
Joel Mueller
Well, if we believe the source comment the parser should throw only in rare unforeseen cases. ("A precaution since custom Parser should never throw in this case.")
0xA3
Fair enough. I was using Reflector, so I missed out on the comment.
Joel Mueller