Une meilleure façon de valider L'URL dans C# que d'essayer-attraper?

je construis une application pour récupérer une image sur internet. Même s'il fonctionne bien, il est lent (sur la mauvaise URL donnée) en utilisant des déclarations try-catch dans l'application.

(1) Est-ce la meilleure façon de vérifier l'URL et la poignée de saisie erronée ou dois-je utiliser des Regex (ou une autre méthode) à la place?

(2) Pourquoi l'application essaie-t-elle de trouver des images localement si Je ne spécifie pas http:// dans la zone de texte?

private void btnGetImage_Click(object sender, EventArgs e)
{
    String url = tbxImageURL.Text;
    byte[] imageData = new byte[1];

    using (WebClient client = new WebClient())
    {
        try
        {
            imageData = client.DownloadData(url);
            using (MemoryStream ms = new MemoryStream(imageData))
            {
                try
                {
                    Image image = Image.FromStream(ms);
                    pbxUrlImage.Image = image;
                }
                catch (ArgumentException)
                {
                    MessageBox.Show("Specified image URL had no match", 
                        "Image Not Found", MessageBoxButtons.OK, 
                        MessageBoxIcon.Error);
                }
            }
        }
        catch (ArgumentException)
        {
            MessageBox.Show("Image URL can not be an empty string", 
                "Empty Field", MessageBoxButtons.OK, 
                MessageBoxIcon.Information);
        }
        catch (WebException)
        {
            MessageBox.Show("Image URL is invalid.nStart with http:// " +
                "and end withna proper image extension", "Not a valid URL",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    } // end of outer using statement
} // end of btnGetImage_Click

EDIT: J'ai essayé la solution suggérée par Panagiotis Kanavos (merci pour votre effort!), mais il est seulement pris dans la déclaration if-else si l'utilisateur entre http:// et rien de plus. Je change pour UriKind.Absolue attrape les cordes à vide! Se rapprocher :) Le code à partir de Maintenant:

private void btnGetImage_Click(object sender, EventArgs e)
{
    String url = tbxImageURL.Text;
    byte[] imageData = new byte[1];
    Uri myUri;

    // changed to UriKind.Absolute to catch empty string
    if (Uri.TryCreate(url, UriKind.Absolute, out myUri))
    {
        using (WebClient client = new WebClient())
        {
            try
            {
                imageData = client.DownloadData(myUri);
                using (MemoryStream ms = new MemoryStream(imageData))
                {
                    imageData = client.DownloadData(myUri);
                    Image image = Image.FromStream(ms);
                    pbxUrlImage.Image = image;
                }
            }
            catch (ArgumentException)
            {
                MessageBox.Show("Specified image URL had no match",
                    "Image Not Found", MessageBoxButtons.OK, 
                    MessageBoxIcon.Error);
            }
            catch (WebException)
            {
                MessageBox.Show("Image URL is invalid.nStart with http:// " +
                    "and end withna proper image extension", 
                    "Not a valid URL",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
    else
    {
        MessageBox.Show("The Image Uri is invalid.nStart with http:// " +
            "and end withna proper image extension", "Uri was not created",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

je dois faire quelque chose de mal ici. : (

59
demandé sur Cœur 2010-07-12 17:29:36

9 réponses

Utiliser Uri.TryCreate pour créer un nouvel objet Uri uniquement si votre chaîne d'url est une URL valide. Si la chaîne n'est pas une URL valide, TryCreate retourne false.

string myString = "http://someUrl";
Uri myUri;
if (Uri.TryCreate(myString, UriKind.RelativeOrAbsolute, out myUri))
{
    //use the uri here
}

mise à JOUR

TryCreate ou l'Uri constructeur serons heureux d'accepter des chaînes qui peuvent apparaître non valide, par exemple, "l'Hôte: www.stackoverflow.com","Host:%20www.stackoverflow.com" ou "chrome:a propos de". En effet, ceux-ci sont parfaitement valables URIs qui spécifient un schéma personnalisé au lieu de "http".

La documentation de la Uri.Scheme propriété fournit plus d'exemples comme "gopher:" (quelqu'un se souvient de cela?), "nouvelles", "mailto", "uuid".

une application peut s'enregistrer comme un gestionnaire de protocole personnalisé tel que décrit dans MSDN ou d'autres questions, par exemple Comment enregistrer un protocole D'URL personnalisé dans Windows?

TryCreate ne fournit pas un moyen de se limiter à des régimes spécifiques. Le code doit vérifier l'Uri.Régime de la propriété pour s'assurer qu'il contient une valeur acceptable

UPDATE 2

passant une chaîne bizarre comme "></script><script>alert(9)</script> retournera true et construira un objet Uri relatif. Appel Uri.IsWellFormedOriginalString retournera false cependant. Donc vous avez probablement besoin d'appeler IsWellFormedOriginalString si vous voulez vous assurer que Uris relatives sont bien formés.

d'autre part, appelant TryCreate avec UriKind.Absolute retournera false dans ce cas.

Fait Intéressant, Uri.IsWellFormedUriString appelle TryCreate internally et retourne ensuite la valeur de IsWellFormedOriginalString si un Uri relatif a été créé.

107
répondu Panagiotis Kanavos 2017-05-23 12:00:20

Un raccourci serait d'utiliser Uri.IsWellFormedUriString :

if (Uri.IsWellFormedUriString(myURL, UriKind.RelativeOrAbsolute))
...
49
répondu Todd Menier 2011-11-01 21:26:35

quelques exemples d'utilisation D'Uri pour tester une URL valide échoue

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

j'ai été surpris de voir toutes ces absurdités apparaître dans mon listview après validation avec ce qui précède. Mais tout passe le test de validation.

maintenant j'Ajoute ce qui suit après la validation ci-dessus

url = url.ToLower();
if (url.StartsWith("http://") || url.StartsWith("https://")) return true;
5
répondu Martin 2012-12-19 19:10:44

Salut vous validez HTTPS http, ftp,sftp,ftps, tout ce qui commence avec 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);
}
4
répondu Naren 2011-12-23 10:14:00

ou ce code source 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;
            }
        }

le Sou et démo asp.net mvc source de l'image:

<img src="@ValidateImage("http://example.com/demo.jpg","nophoto.png")"/>
3
répondu Elyor 2011-12-01 10:05:19

ma solution:

string regular = @"^(ht|f|sf)tp(s?)\:\/\/[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
{
    MessageBox.Show("InValide url  " + myString);
}
3
répondu Naren 2011-12-22 13:45:11

utilisez-le.....

string myString = http//:google.com;
Uri myUri;
Uri.TryCreate(myString, UriKind.RelativeOrAbsolute, out myUri);
 if (myUri.IsAbsoluteUri == false)
 {
  MessageBox.Show("Please Input Valid Feed Url");
 }
3
répondu Shivam Srivastava 2015-01-01 10:25:07

vous pouvez utiliser la fonction Uri.TryCreate comme Panagiotis Kanavos suggéré si vous aimez tester et créer une url ou vous pouvez utiliser Uri.IsWellFormedUriString fonction comme suggéré par Todd Menier si vous vouliez juste tester la validité de L'Url. cela peut être pratique si vous validez simplement l'entrée de l'utilisateur pour le moment et avez besoin de créer l'url un certain temps plus tard dans le temps de vie de votre application.

**, Mais mon post est pour les Personnes qui, comme moi * 151980920"

les deux méthodes ci-dessus ont été introduites dans .net 2.0 donc vous devez toujours utiliser la méthode try catch, qui, à mon avis, est encore beaucoup mieux que l'utilisation de l'expression régulière.

private bool IsValidHTTPURL(string url)
{
    bool result = false;

    try
    {
        Uri uri = new Uri(url);

        result = (uri.Scheme == "http" || uri.Scheme == "https");
    }
    catch (Exception ex) 
    { 
        log.Error("Exception while validating url", ex); 
    }

    return result;
}
2
répondu Mubashar Ahmad 2017-05-23 12:33:35

je voulais vérifier si l'url contient aussi une extension de domaine, elle doit être une url de site web valide.

C'est ce que j'ai trouvé:

 public static bool IsValidUrl(string url)
        {
            if (string.IsNullOrEmpty(url)) { return false;}

            if (!url.StartsWith("http://"))
            {
                url = "http://" + url;    
            }

            Uri outWebsite;

            return Uri.TryCreate(url, UriKind.Absolute, out outWebsite) && outWebsite.Host.Replace("www.", "").Split('.').Count() > 1 && outWebsite.HostNameType == UriHostNameType.Dns && outWebsite.Host.Length > outWebsite.Host.LastIndexOf(".") + 1 && 255 >= url.Length;
        }

j'ai testé le code avec linqpad:

    void Main()
{
        // Errors
        IsValidUrl("www.google/cookie.png").Dump();
        IsValidUrl("1234").Dump();
        IsValidUrl("abcdef").Dump();
        IsValidUrl("abcdef/test.png").Dump();
        IsValidUrl("www.org").Dump();
        IsValidUrl("google").Dump();
        IsValidUrl("google.").Dump();
        IsValidUrl("google/test").Dump();
        IsValidUrl("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0").Dump();
        IsValidUrl("</script><script>alert(9)</script>").Dump();
        IsValidUrl("Accept: application/json, text/javascript, */*; q=0.01").Dump();
        IsValidUrl("DNT: 1").Dump();

        Environment.NewLine.Dump();

        // Success
        IsValidUrl("google.nl").Dump();
        IsValidUrl("www.google.nl").Dump();
        IsValidUrl("http://google.nl").Dump();
        IsValidUrl("http://www.google.nl").Dump();
}

Résultats:

False False False False False False False False False False False Faux

True True True True

1
répondu Jamie 2015-06-07 16:06:18