Я создаю приложение для извлечения изображения из Интернета. Несмотря на то, что он работает нормально, он медленный (при неправильном заданном URL) при использовании утверждений try-catch в приложении.
(1) Это лучший способ проверить URL-адрес и обработать неправильный ввод - или я должен использовать Regex (или какой-либо другой метод)?
(2) Почему приложение пытается найти изображения локально, если я не укажу http://в текстовом поле?
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
EDIT:
Я попробовал предложенное решение Panagiotis Kanavos (спасибо вам за ваши усилия!), Но он попадает только в оператор if-else, если пользователь вводит http://
и ничего больше. Переход на UriKind.Absolute также улавливает пустые строки! Поближе:)
Код на данный момент:
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);
}
Я должен делать что-то не так.: (
Ответ 1
Используйте Uri.TryCreate, чтобы создать новый объект Uri, только если ваша строка URL-адреса является допустимым URL-адресом. Если строка не является допустимым URL, TryCreate возвращает false.
string myString = "http://someUrl";
Uri myUri;
if (Uri.TryCreate(myString, UriKind.RelativeOrAbsolute, out myUri))
{
//use the uri here
}
UPDATE
TryCreate или конструктор Uri с радостью принимают строки, которые могут оказаться недействительными, например "Host: www.stackoverflow.com", "Host: %20www.stackoverflow.com" или "chrome: about". Фактически, это вполне допустимые URI, которые определяют пользовательскую схему вместо "http".
Документация свойства Uri.Scheme дает больше примеров, таких как "gopher:" (кто-нибудь помнит это?), "новости", "mailto", "uuid".
Приложение может регистрироваться как пользовательский обработчик протокола, как описано в MSDN или другие вопросы SO, например Как зарегистрировать собственный протокол URL в Windows?
TryCreate не предоставляет способ ограничить себя конкретными схемами. Код должен проверить свойство Uri.Scheme, чтобы убедиться, что он содержит допустимое значение
ОБНОВЛЕНИЕ 2
Передача странной строки, такой как "></script><script>alert(9)</script>
, вернет true
и построит относительный объект Uri. Вызов Uri.IsWellFormedOriginalString вернет false, хотя. Поэтому вам, вероятно, нужно вызвать IsWellFormedOriginalString
, если вы хотите, чтобы относительный Uris был хорошо сформирован.
С другой стороны, вызов TryCreate
с UriKind.Absolute
в этом случае вернет false.
Интересно, что Uri.IsWellFormedUriString вызывает TryCreate внутри, а затем возвращает значение IsWellFormedOriginalString
, если был создан относительный Uri.
Ответ 2
Ярлык должен был бы использовать Uri.IsWellFormedUriString:
if (Uri.IsWellFormedUriString(myURL, UriKind.RelativeOrAbsolute))
...
Ответ 3
Некоторые примеры использования Uri для проверки допустимого URL-адреса терпят неудачу
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))
{
}
Я был удивлен тем, что вся эта глупость появилась в моем списке после проверки с помощью вышеизложенного. Но все это проходит проверку валидации.
Теперь я добавлю следующее после указанной выше проверки
url = url.ToLower();
if (url.StartsWith("http://") || url.StartsWith("https://")) return true;
Ответ 4
Привет, вы проверяете https http, ftp, sftp, ftps, любую вещь, начиная с 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);
}
Ответ 5
Или этот исходный код хорошая правильная оптимизация изображения:
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;
}
}
Су и демо asp.net mvc исходное изображение создано:
<img src="@ValidateImage("http://example.com/demo.jpg","nophoto.png")"/>
Ответ 6
Мое решение:
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);
}
Ответ 7
Используйте его.....
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");
}
Ответ 8
вы можете использовать функцию Uri.TryCreate
As Panagiotis Kanavos, если вы хотите протестировать и создать URL-адрес, или вы можете использовать функцию Uri.IsWellFormedUriString
, как предложено Todd Menier, если вы просто хотели проверить правильность Url. это может быть удобно, если вы просто проверяете ввод пользователя на данный момент и должны создать URL-адрес через некоторое время в течение срока вашего приложения.
** Но мой пост для Людей, как и я:(, все еще ударяя головой против .net 1.1 **
оба вышеуказанных метода были введены в .net 2.0, поэтому вам, ребятам, еще нужно использовать метод try catch, который, на мой взгляд, все же намного лучше, чем использование регулярного выражения.
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;
}
Ответ 9
Я хотел проверить, содержит ли URL-адрес расширение домена, он должен быть действительным URL-адресом веб-сайта.
Вот что я придумал:
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;
}
Я тестировал код с помощью 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();
}
Результаты:
False False False False False False False False False False False False
True True True True