To create a Uri from a string you can do this:
Uri u = new Uri(\"example.com\");
But the problem is if the string (like the one above) does
We had some specific cases where there was a legacy allowance to input stuff like: localhost:8800 or similar. Which means we needed to parse that. We built a little more elaborate ParseUri method that separated the possibility to specify a URI very loosely, but also caught the times where people would specify a non-standard scheme (and also the host in IP-long notation, because sometimes people do that)
Just like UriBuilder it will default to the http scheme if none is specified. It will have issues if a basic authentication is specified and the password consists only of numbers. (Feel free to fix that community)
private static Uri ParseUri(string uri)
{
if (uri.StartsWith("//"))
return new Uri("http:" + uri);
if (uri.StartsWith("://"))
return new Uri("http" + uri);
var m = System.Text.RegularExpressions.Regex.Match(uri, @"^([^\/]+):(\d+)(\/*)", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);
if (m.Success)
{
var port = int.Parse(m.Groups[2].Value);
if (port <= 65535) //part2 is a port (65535 highest port number)
return new Uri("http://" + uri);
else if (port >= 16777217) //part2 is an ip long (16777217 first ip in long notation)
return new UriBuilder(uri).Uri;
else
throw new ArgumentOutOfRangeException("Invalid port or ip long, technically could be local network hostname, but someone needs to be hit on the head for that one");
}
else
return new Uri(uri);
}
If you just want to add the scheme, without validating the URL, the fastest/easiest way is to use string lookups, eg:
string url = "mydomain.com";
if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) url = "http://" + url;
A better approach would be to use Uri to also validate the URL using the TryCreate method:
string url = "mydomain.com";
Uri uri;
if ((Uri.TryCreate(url, UriKind.Absolute, out uri) || Uri.TryCreate("http://" + url, UriKind.Absolute, out uri)) &&
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
{
// Use validated URI here
}
As @JanDavidNarkiewicz pointed out in the comments, validating the Scheme
is necessary to guard against invalid schemes when a port is specified without scheme, e.g. mydomain.com:80
.
You could also use UriBuilder:
public static Uri GetUri(this string s)
{
return new UriBuilder(s).Uri;
}
Remarks from MSDN:
This constructor initializes a new instance of the UriBuilder class with the Fragment, Host, Path, Port, Query, Scheme, and Uri properties set as specified in uri.
If uri does not specify a scheme, the scheme defaults to "http:".
Interestingly, although Uri
and UriBuilder
completely mangle any url without a scheme, WebProxy
does it right.
So just call:
new WebProxy(proxy.ProxyServer).Address
My solution was for protocall-less urls to make sure they have protocal was regex :
Regex.Replace(s, @"^\/\/", "http://");