2010-07-12 11 views
59

मैं इंटरनेट से एक छवि पुनर्प्राप्त करने के लिए एक आवेदन बना रहा हूँ। भले ही यह ठीक काम करता है, एप्लिकेशन में प्रयास-पकड़ विवरणों का उपयोग करते समय धीमा (गलत दिया गया URL पर) धीमा है।कोशिश-पकड़ से सी # में यूआरएल को प्रमाणित करने का एक बेहतर तरीका?

(1) क्या यह यूआरएल सत्यापित करने और गलत इनपुट को संभालने का सबसे अच्छा तरीका है - या मुझे इसके बजाय रेगेक्स (या कुछ अन्य विधि) का उपयोग करना चाहिए?

(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 

संपादित करें: मैं पानागिओटिस Kanavos ने सुझाव दिया समाधान की कोशिश की (यदि आप अपने प्रयास के लिए धन्यवाद!), लेकिन यह केवल यदि-बाकी बयान में पकड़ा जाता है, तो उपयोगकर्ता 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

आप कैसे जानते हैं कि 'ArgumentException' या' WebException' का अर्थ यूआरएल के साथ एक समस्या है? –

+0

यह डिबगिंग के दौरान मुझे प्राप्त अपवाद था। लेकिन मैं सहमत हूं - इंटरनेट से कई प्रकार के अपवाद डाउनलोड हो सकते हैं। आपके त्वरित उत्तर के लिए –

उत्तर

105

उपयोग Uri.TryCreate एक नया उरी वस्तु बनाने के लिए केवल यदि आपके url स्ट्रिंग एक मान्य URL है। स्ट्रिंग एक मान्य URL नहीं है, तो TryCreate झूठी देता है।

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

अद्यतन

TryCreate या उरी कन्स्ट्रक्टर खुशी से उन तारों को स्वीकार करेगा जो अमान्य दिखाई दे सकते हैं, उदाहरण के लिए "होस्ट: www.stackoverflow.com", "होस्ट:% 20www.stackoverflow.com" या "क्रोम: के बारे में"। वास्तव में, ये पूरी तरह से मान्य हैं यूआरआई जो "http" के बजाय एक कस्टम योजना निर्दिष्ट करते हैं।

Uri.Scheme संपत्ति का दस्तावेज "गोफर:" (किसी को यह याद है?), "समाचार", "mailto", "uuid" जैसे अधिक उदाहरण प्रदान करता है।

एक आवेदन MSDN या अन्य अतः सवाल में बताए अनुसार एक कस्टम प्रोटोकॉल हैंडलर के रूप में रजिस्टर कर सकते हैं, जैसे How do I register a custom URL protocol in Windows?

TryCreate विशिष्ट योजनाओं के लिए खुद को सीमित करने के लिए एक तरीका प्रदान नहीं करता है। कोड Uri.Scheme संपत्ति की जांच करने के लिए सुनिश्चित करें कि यह एक स्वीकार्य मूल्य

अद्यतन 2

पासिंग "></script><script>alert(9)</script> की तरह एक अजीब स्ट्रिंग true लौट सकते हैं और एक रिश्तेदार उरी वस्तु का निर्माण करेगी शामिल की जरूरत है। कॉलिंग Uri.IsWellFormedOriginalString हालांकि झूठी वापसी होगी। इसलिए यदि आप यह सुनिश्चित करना चाहते हैं कि सापेक्ष उरी अच्छी तरह से बने हैं तो आपको शायद IsWellFormedOriginalString पर कॉल करने की आवश्यकता है।

दूसरी ओर, TryCreateUriKind.Absolute के साथ इस मामले में झूठी वापसी होगी।

दिलचस्प बात यह है कि Uri.IsWellFormedUriString आंतरिक रूप से TryCreate को कॉल करता है और फिर IsWellFormedOriginalString का मान देता है यदि कोई सापेक्ष उरी बनाया गया था।

+0

Thanx! बीआर –

+0

धन्यवाद दोस्त !!! रेगेक्स का उपयोग करने से बेहतर तरीका! – TheGateKeeper

+0

यह "विफल: www.stackoverflow.com" जैसे हेडर स्ट्रिंग में पास होने पर विफल रहता है। असफल होने का मतलब है, इसे एक अवैध यूआरएल – Martin

49

एक शॉर्टकट का उपयोग किया जाएगा Uri.IsWellFormedUriString:

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

कहते हैं बेहतर अगर आप केवल यूआरएल जांचना चाहते हैं। TryCreate एक ही चरण में उपयोग करने के लिए उरी भी बनाएगा। –

+5

यह वास्तव में पूछे जाने वाले प्रश्न का सबसे अच्छा जवाब है। ठीक है। –

+0

दरअसल, IsWellFormedUriString वास्तव में TryCreate को कॉल करने के लिए कॉल करता है या नहीं यूआरएल वैध है लेकिन फिर जांचता है कि लौटा हुआ यूरी यूरी से सच है या नहीं। IWellFormedOriginalString()। –

3

या इस स्रोत कोड अच्छी छवि वैध अनुकूलन:

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")"/> 
3

मेरा समाधान:

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

कुछ उदाहरण जब उरी एक मान्य 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; 
2

आप अगर आप का परीक्षण और एक URL बनाना चाहते Uri.TryCreatePanagiotis Kanavos के रूप में सुझाव दिया फ़ंक्शन का उपयोग कर सकते हैं या के रूप में Todd Menier ने सुझाव दिया कि आप Uri.IsWellFormedUriString समारोह का उपयोग कर सकते है अगर आप बस यूआरएल की वैधता का परीक्षण करना चाहता था। यह आसान हो सकता है अगर आप अभी के लिए उपयोगकर्ता इनपुट को मान्य कर रहे हैं और कुछ समय बाद अपने आवेदन के जीवनकाल में यूआरएल बनाने की जरूरत है।

** लेकिन मेरी पोस्ट अपने आप की तरह, लोगों के लिए है :(, अभी भी .net 1.1 **

के खिलाफ उनके सिर से टकराने के उपरोक्त दोनों तरीकों .net 2.0 में पेश किए गए, ताकि आप अभी भी कोशिश का उपयोग करना पकड़ विधि है, जो, मेरी राय में, अभी भी रेगुलर एक्सप्रेशन के उपयोग से बेहतर है।

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

इसका इस्तेमाल .....

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

मैं अगर यूआरएल भी एक डोमेन शामिल जाँच करना चाहता था विस्तार, यह नी एक वैध वेबसाइट यूआरएल होने के लिए डीएस।

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

परिणाम::

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 साथ कोड परीक्षण किया है:

यह क्या मैं के साथ आया है

झूठी झूठी झूठी झूठी झूठी झूठी झूठी झूठी झूठी झूठी झूठी झूठी

ट्रू ट्रू ट्रू ट्रू

संबंधित मुद्दे