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. : (
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éé.
Un raccourci serait d'utiliser Uri.IsWellFormedUriString :
if (Uri.IsWellFormedUriString(myURL, UriKind.RelativeOrAbsolute))
...
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;
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\-\.\?\,\'\/\\+&%$#_]*)?$";
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);
}
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")"/>
ma solution:
string regular = @"^(ht|f|sf)tp(s?)\:\/\/[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
{
MessageBox.Show("InValide url " + myString);
}
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");
}
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;
}
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