64 votes

Un meilleur moyen de valider une URL en C # que try-catch?

Je suis en train de construire une application pour récupérer une image à partir d'internet. Même si elle fonctionne bien, elle est lente (sur le mauvais compte tenu de l'URL) lors de l'utilisation de try-catch déclarations dans la demande.

(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, essayez de trouver des images localement si je n'ai pas spécifier 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 with\na proper image extension", "Not a valid URL",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    } // end of outer using statement
} // end of btnGetImage_Click

Merci pour votre temps!

EDIT: J'ai essayé la solution proposée par m. Panagiotis Kanavos (merci pour votre effort!), mais il ne se fait attraper dans le if-else si l'utilisateur saisit http:// et rien de plus. Changer de UriKind.Absolue attrape les cordes à vide! L'obtention de plus près :) Le code dès 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 with\na proper image extension", 
                    "Not a valid URL",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
    else
    {
        MessageBox.Show("The Image Uri is invalid.\nStart with http:// " +
            "and end with\na proper image extension", "Uri was not created",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

Je dois être en train de faire quelque chose de mal ici :(

112voto

Panagiotis Kanavos Points 14085

L'Utilisation D'Uri.TryCreate pour créer un nouvel objet Uri seulement si votre url est une URL valide. Si la chaîne n'est pas une URL valide, TryCreate renvoie la valeur 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 Uri spécifier un modèle personnalisé au lieu de "http".

La documentation de l' Uri.Régime de propriété fournit d'autres exemples comme "gopher:" (quelqu'un se souvient?), "news", "mailto", "uuid".

Une application peut s'inscrire en tant que gestionnaire de protocole personnalisé comme décrit dans la MSDN et d'autres questions, par exemple, Comment puis-je enregistrer une URL personnalisée protocole dans Windows?

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

Mise à JOUR 2

Le passage d'un étrange chaîne comme "></script><script>alert(9)</script> sera de retour true et la construction d'un Uri relatif de l'objet. L'Appel D'Uri.IsWellFormedOriginalString retournera false si. Donc, vous avez probablement besoin d'appeler IsWellFormedOriginalString si vous voulez vous assurer que Uris relatives sont bien formés.

D'autre part, l'appelant TryCreate avec UriKind.Absolute retournera false dans le cas présent.

Il Est Intéressant De Noter, D'Uri.IsWellFormedUriString appels TryCreate en interne, puis renvoie la valeur de IsWellFormedOriginalString si un Uri relatif a été créé.

54voto

Todd Menier Points 3599

Un raccourci serait d'utiliser Uri.IsWellFormedUriString :

 if (Uri.IsWellFormedUriString(myURL, UriKind.RelativeOrAbsolute))
...
 

5voto

Martin Points 359

Quelques exemples d'utilisation d'Uri pour tester une URL valide échouent

 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 ma liste 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;
 

3voto

elyor Points 406

Ou ce code source bonne image optimisation valide:

  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 et démo asp.net mvc image source créée:

 <img src="@ValidateImage("http://example.com/demo.jpg","nophoto.png")"/>
 

2voto

Naren Points 41

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X