I\'m building an application to retrieve an image from internet. Even though it works fine, it is slow (on wrong given URL) when using try-catch statements in the applicatio
I ran into a very similar case so I wrote a static class which can be easily used along with xUnit tests to verify the logic passed several cases.
Usage (returns ValidationModel
):
var message = UrlValidator.Validate(input).ValidationMessage;
or
var result = UrlValidator.Validate(input).IsValid;
public class ValidationModel
{
public const string InvalidScheme = "Invalid URI scheme.";
public const string EmptyInputValue = "Empty input value.";
public const string InvalidUriFormat = "Invalid URI format.";
public const string PassedValidation = "Passed validation";
public const string HttpScheme = "http://";
public const string HttpsScheme = "https://";
public bool IsValid { get; set; }
public string ValidationMessage { get; set; }
}
public static class UrlValidator
{
public static ValidationModel Validate(string input)
{
var validation = new ValidationModel();
if (input == string.Empty)
{
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.EmptyInputValue;
return validation;
}
try
{
var uri = new Uri(input);
var leftPart = uri.GetLeftPart(UriPartial.Scheme);
if (leftPart.Equals(ValidationModel.HttpScheme) || leftPart.Equals(ValidationModel.HttpsScheme))
{
validation.IsValid = true;
validation.ValidationMessage = ValidationModel.PassedValidation;
return validation;
}
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.InvalidScheme;
}
catch (UriFormatException)
{
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.InvalidUriFormat;
}
return validation;
}
}
public class UrlValidatorTests
{
[Theory]
[InlineData("http://intel.com", true, ValidationModel.PassedValidation)]
[InlineData("https://intel.com", true, ValidationModel.PassedValidation)]
[InlineData("https://intel.com/index.html", true, ValidationModel.PassedValidation)]
[InlineData("", false, ValidationModel.EmptyInputValue)]
[InlineData("http://", false, ValidationModel.InvalidUriFormat)]
[InlineData("//intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("://intel.com", false, ValidationModel.InvalidUriFormat)]
[InlineData("f://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("htttp://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("intel.com", false, ValidationModel.InvalidUriFormat)]
[InlineData("ftp://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("http:intel.com", false, ValidationModel.InvalidUriFormat)]
public void Validate_Input_ExpectedResult(string input, bool expectedResult, string expectedInvalidMessage)
{
//Act
var result = UrlValidator.Validate(input);
//Assert
Assert.Equal(expectedResult, result.IsValid);
Assert.Equal(expectedInvalidMessage, result.ValidationMessage);
}
}
Or this source code good image valid optimization:
public static string ValidateImage(string absoluteUrl,string defaultUrl)
{
Uri myUri=null;
if (Uri.TryCreate(absoluteUrl, UriKind.Absolute, out myUri))
{
using (WebClient client = new WebClient())
{
try
{
using (Stream stream = client.OpenRead(myUri))
{
Image image = Image.FromStream(stream);
return (image != null) ? absoluteUrl : defaultUrl;
}
}
catch (ArgumentException)
{
return defaultUrl;
}
catch (WebException)
{
return defaultUrl;
}
}
}
else
{
return defaultUrl;
}
}
Sou and demo asp.net mvc source image created:
<img src="@ValidateImage("http://example.com/demo.jpg","nophoto.png")"/>
Hi you validate https http,ftp,sftp,ftps,any thing starting with www.
string regular = @"^(ht|f|sf)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$";
string regular123 = @"^(www.)[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$";
string myString = textBox1.Text.Trim();
if (Regex.IsMatch(myString, regular))
{
MessageBox.Show("It is valide url " + myString);
}
else if (Regex.IsMatch(myString, regular123))
{
MessageBox.Show("Valide url with www. " + myString);
}
else
{
MessageBox.Show("InValide URL " + myString);
}
Some examples when using Uri to test a valid URL fails
Uri myUri = null;
if (Uri.TryCreate("Host: www.stackoverflow.com", UriKind.Absolute, out myUri))
{
}
myUri = null;
if (Uri.TryCreate("Accept: application/json, text/javascript, */*; q=0.01", UriKind.Absolute, out myUri))
{
}
myUri = null;
if (Uri.TryCreate("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0", UriKind.Absolute, out myUri))
{
}
myUri = null;
if (Uri.TryCreate("DNT: 1", UriKind.Absolute, out myUri))
{
}
I Was surprised to have all this nonsense appear in my listview after validating with the above. But it all passes the validation test.
Now I add the following after the above validation
url = url.ToLower();
if (url.StartsWith("http://") || url.StartsWith("https://")) return true;