在C#中validationURL的一个更好的方法比try-catch?

我正在构build一个应用程序来从互联网上检索图像。 即使它工作正常,但在应用程序中使用try-catch语句时,速度很慢(错误的给定的URL)。

(1)这是validationURL和处理错误input的最好方法 – 或者我应该使用正则expression式(或其他方法)吗?

(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 

编辑:我尝试了由Panagiotis Kanavos(谢谢你的努力!)build议的解决scheme,但它只捕获if-else语句,如果用户inputhttp://和没有更多。 更改为UriKind.Absolute也捕获空string! 越来越近:)现在的代码:

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

我一定在这里做错了什么 🙁

只有当您的urlstring是有效的URL时,才使用Uri.TryCreate创build新的Uri对象。 如果该string不是有效的URL,则TryCreate返回false。

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

UPDATE

TryCreate或Uri构造函数将愉快地接受可能看起来无效的string,例如“Host:www.stackoverflow.com”,“Host:%20www.stackoverflow.com”或“chrome:about”。 实际上,这些是完全有效的URI,它们指定了一个自定义scheme而不是“http”。

Uri.Scheme属性的文档提供了更多的例子,例如“gopher:”(任何人都记得这个?),“news”,“mailto”,“uuid”。

应用程序可以注册自己作为自定义协议处理程序,如MSDN或其他SO问题中所述,例如, 如何在Windows中注册自定义URL协议?

TryCreate不提供限制自己到特定scheme的方法。 代码需要检查Uri.Scheme属性以确保它包含可接受的值

更新2

传递一个像"></script><script>alert(9)</script>这样的奇怪的string将返回true并构造一个相对的Uri对象,调用Uri.IsWellFormedOriginalString将会返回false,所以你可能需要调用IsWellFormedOriginalString要确保相对Uris形成良好。

另一方面,使用UriKind.Absolute调用UriKind.Absolute将在这种情况下返回false。

有趣的是,Uri.IsWellFormedUriString在内部调用TryCreate,如果创build了相对Uri,则返回IsWellFormedOriginalString的值。

一个捷径是使用Uri.IsWellFormedUriString :

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

使用Uritesting有效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)) { } 

我感到惊讶的是,所有这些废话出现在我的列表视图validation与上述。 但都通过了validationtesting。

现在我在上面的validation后添加以下内容

 url = url.ToLower(); if (url.StartsWith("http://") || url.StartsWith("https://")) return true; 

嗨,你validationhttps 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\-\.\?\,\'\/\\\+&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); } 

或者这个源代码好的图片有效优化:

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

search和演示asp.net mvc源图像创build:

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

我的解决scheme

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

用它…..

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

你可以使用函数Uri.TryCreate如Panagiotis Kanavosbuild议如果你想testing和创build一个url,或者你可以使用Uri.IsWellFormedUriString函数如Todd Menier所build议的,如果你只是想testingUrl的有效性。 如果您现在只是validation用户input,并且需要在应用程序的生命周期的某个时间后创buildURL,则可以方便地使用它。

**但我的post是为人民,像我自己:(仍然击中他们的头.net 1.1 **

上述两种方法都是在.net 2.0中引入的,所以你们仍然需要使用try catch方法,在我看来,它仍然比使用正则expression式要好。

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

我想检查,如果该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; } 

我已经用linqpadtesting了代码:

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

结果:

假假假假假假假假假假假假假假

真正的真实的真实