A better way to validate URL in C# than try-catch?

前端 未结 10 957
栀梦
栀梦 2020-12-13 12:08

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

相关标签:
10条回答
  • 2020-12-13 12:38

    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;

    ValidationModel.cs

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

    UrlValidator.cs

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

    UrlValidatorTests.cs

        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);
            }
        }
    

    TEST RESULTS:

    0 讨论(0)
  • 2020-12-13 12:52

    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")"/>
    
    0 讨论(0)
  • 2020-12-13 12:54

    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\-\.\?\,\'\/\\\+&amp;%\$#_]*)?$";
    string regular123 = @"^(www.)[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?$";
    
    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);
    }
    
    0 讨论(0)
  • 2020-12-13 12:56

    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;
    
    0 讨论(0)
提交回复
热议问题