2017-05-10 85 views
0

我一直在摸索我的頭一陣子,試圖找到解決方案,我一直沒能找到任何東西在谷歌上搜索相關時,所以經過數小時試圖找到這個問題背後的原因,我試圖尋求幫助在這裏..VB.net - 向datagridview添加一行返回InvalidArgument =值'8797'對'rowIndex'無效

奇怪的是,錯誤不會馬上發生,但在隨機時間通常在檢查了幾千行之後。

應用程序本身是一個鏈接提取器,它從不同的URI中提取鏈接,然後當它找到新的內部鏈接時,它將它們添加到datagridview。

當我看一些的IntelliTrace例外,它說的錯誤是在這行拋出: See image here

或者在代碼..

DataGridView1.Rows.Add(New String() {HttpUtility.HtmlDecode(matchUrl), anchor_txt, "", "", "", True}) 

它並沒有真正意義的我爲什麼它會拋出如此高的索引整數,特別是不在這一行,當它所做的只是添加一個新行。無論如何,索引可能存在於某一點,但對於每次掃描,我刪除了那些不包含x字符串,然後我再次掃描鏈接,直到沒有剩下。

這裏有一個堆棧跟蹤,如果它可以在任何幫助:

System.ArgumentException: InvalidArgument=Værdi '8797' er ugyldig for 'rowIndex'. 
ved System.Windows.Forms.DataGridViewRow.GetState(Int32 rowIndex) 
ved System.Windows.Forms.DataGridViewRowCollection.GetRowState(Int32 rowIndex) 
ved System.Windows.Forms.DataGridViewRowCollection.UpdateRowCaches(Int32 rowIndex, DataGridViewRow& dataGridViewRow, Boolean adding) 
ved System.Windows.Forms.DataGridViewRowCollection.OnCollectionChanged_PreNotification(CollectionChangeAction cca, Int32 rowIndex, Int32 rowCount, DataGridViewRow& dataGridViewRow, Boolean changeIsInsertion) 
ved System.Windows.Forms.DataGridViewRowCollection.OnCollectionChanged(CollectionChangeEventArgs e, Int32 rowIndex, Int32 rowCount) 
ved System.Windows.Forms.DataGridViewRowCollection.AddInternal(Boolean newRow, Object[] values) 
ved System.Windows.Forms.DataGridViewRowCollection.Add(Object[] values) 
ved Link_Extractor.Form1.InternalThread2() i C:\Users\USER\Documents\Visual Studio 2010\Projects\Link\Link\Form1.vb:linje 568 

我也收到在「對於每個」行「對象引用未設置爲對象的實例」或NullReferenceException異常。我想這可能是如果單元格(0)是由於某種原因空 - 我會檢查這一點,但仍然沒有解釋第一個。

For Each itm As DataGridViewRow In DataGridView1.Rows 
    If itm.Cells(0).Value = HttpUtility.HtmlDecode(matchUrl) Then 
      exists = True 
    End If 
Next 

如果是這種堆棧跟蹤:

System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt. 
ved System.Windows.Forms.DataGridViewRowCollection.OnCollectionChanged(CollectionChangeEventArgs e, Int32 rowIndex, Int32 rowCount) 
ved System.Windows.Forms.DataGridViewRowCollection.AddInternal(Boolean newRow, Object[] values) 
ved System.Windows.Forms.DataGridViewRowCollection.Add(Object[] values) 
ved Link_Extractor.Form1.InternalThread3() i C:\Users\USER\Documents\Visual Studio 2010\Projects\Link\Link\Form1.vb:linje 808 

編輯 這裏的一些代碼,它接收到的html頁面後。

If Not data = "" Then 

        Dim links As MatchCollection = Regex.Matches(data, "<a.*?href=[""']?([^'"">\ ]*)[""']?[^>]*>([\s\S]*?)<\/a>") 

        For Each match As Match In links 

         Dim matchUrl As String = HttpUtility.HtmlDecode(match.Groups(1).Value) 
         Dim anchor As String = HttpUtility.HtmlDecode(StripTags(match.Groups(2).Value)) 

         'Ignore all anchor links 
         If matchUrl.StartsWith("#") Then 
          Continue For 
         End If 
         'Ignore all javascript calls 
         If matchUrl.ToLower.StartsWith("javascript:") Then 
          Continue For 
         End If 
         'Ignore all email links 
         If matchUrl.ToLower.StartsWith("mailto:") Then 
          Continue For 
         End If 
         'Ignore all URLs with @ 
         If matchUrl.ToLower.Contains("@") Then 
          Continue For 
         End If 
         'Ignore all empty domains 
         If matchUrl Is Nothing Then 
          Throw New Exception("Empty matchurl") 
         End If 
         If anchor Is Nothing Then 
          Throw New Exception("Empty anchor text.") 
         End If 
         'For internal links, build the url mapped to the base address 

         If Not matchUrl.StartsWith("http://") And Not matchUrl.StartsWith("https://") Then 

          'Højst sansynligt internt link 
          matchUrl = MapUrl(url, matchUrl) 
          Try 
           exists = False 
           For Each itm As DataGridViewRow In DataGridView1.Rows 
            If Not itm.Cells(0) Is Nothing Then 
             If itm.Cells(0).Value = matchUrl Then 
              exists = True 
              Exit For 
             End If 
            End If 
           Next 
           If DataGridView1.Rows.Count > 0 AndAlso exists = True Then 
            Continue For 
           Else 
            DataGridView1.Rows.Add(New String() {matchUrl, anchor, "", "", "", True}) 
           End If 
          Catch ex As Exception 
           MessageBox.Show(ex.Message) 
          End Try 

         Else 

          'It's possible that it still can be an internal link, but also external. Compare the baseaddress with the URL to check if it's still the same domain 

          Dim baseaddress As Uri = New Uri(url) 
          Dim s_baseaddress As String = baseaddress.Host.ToString 
          'Check for subdomain and remove 
          If s_baseaddress.ToCharArray().Count(Function(c) c = "."c) >= 2 Then 
           Dim subdomain As String = Split(s_baseaddress, ".").First 
           s_baseaddress = s_baseaddress.Replace(subdomain & ".", "") 
          End If 

          Dim s_url As String = Nothing 
          Dim url2 As Uri = Nothing 
          Try 
           url2 = New Uri(HttpUtility.HtmlDecode(matchUrl)) 
           s_url = url2.Host.ToString 
           If s_url.ToCharArray().Count(Function(c) c = "."c) >= 2 Then 
            Dim subdomain As String = Split(s_url, ".").First 
            s_url = s_url.Replace(subdomain & ".", "") 
           End If 
          Catch ex As Exception 
           'Invalid URI 
           Continue For 
          End Try 

          If s_baseaddress.Equals(s_url) Then 

           'Internal 

           Try 

            exists = False 
            For Each itm As DataGridViewRow In DataGridView1.Rows 
             If Not itm.Cells(0) Is Nothing Then 
              If itm.Cells(0).Value = matchUrl Then 
               exists = True 
               Exit For 
              End If 
             End If 
            Next 
            If DataGridView1.Rows.Count > 0 AndAlso exists = True Then 
             Continue For 
            Else 
             DataGridView1.Rows.Add(New String() {matchUrl, anchor, "", "", "", True}) 
            End If 

           Catch ex As Exception 
            MessageBox.Show(ex.Message) 
           End Try 

          Else 

           'External link 
           Dim m_url As String = matchUrl 
           m_url = m_url.Replace(" ", "") 

           'Trim url to root to save the time of removing duplicates 
           Dim theUri = Nothing 
           Try 
            theUri = New Uri(m_url) 
           Catch ex As Exception 
            'Invalid link, go to next 
            Continue For 
           End Try 
           Dim theDomain = theUri.GetLeftPart(UriPartial.Authority) 

           Try 

            exists = False 
            For Each itm As DataGridViewRow In DataGridView2.Rows 
             If Not itm.Cells(0) Is Nothing Then 
              If itm.Cells(0).Value = theDomain.ToString Then 
               exists = True 
               Exit For 
              End If 
             End If 
            Next 
            If DataGridView2.Rows.Count > 0 AndAlso exists = True Then 
             Continue For 
            Else 
             DataGridView2.Rows.Add(New String() {theDomain.ToString, anchor, ""}) 
             e_links_c += 1 
            End If 

           Catch ex As Exception 
            MessageBox.Show(ex.Message) 
           End Try 

          End If 

         End If 

        Next 

        'OK 
        DataGridView1.Rows(thi3).Cells(2).Value = "OK" 
        DataGridView1.Rows(thi3).Cells(3).Value = e_links_c.ToString 

       Else 
        'Error 
        DataGridView1.Rows(thi3).Cells(2).Value = "Empty response" 

       End If 

回答

0

看起來HttpUtility.HtmlDecode(matchUrl)給你無效的數據。由於你的代碼片段有Continue For,我的假設是你有2個For循環。

  1. 您確定matchUrl有效嗎?
  2. 驗證HttpUtility.HtmlDecode(matchUrl)值之前添加到行,並在If條件中使用它之前。雖然你驗證了anchor_txt
  3. 代碼片段不顯示TryCatch塊。如果你不使用它,請這樣做。
  4. 在內部使用Exit ForFor循環後,exists = True聲明。
  5. 代碼在兩個不同的實例中評估HttpUtility.HtmlDecode(matchUrl),並且在內部For循環中對其進行多次評估。在For循環之前將其值賦給一個變量。驗證輸出,然後在For循環中使用此值。

試試下面的代碼: -

Try 
    exists = False 
    urlDecode = HttpUtility.HtmlDecode(matchUrl) 'Put a break point on this statement and check the value of matchUrl and HttpUtility.HtmlDecode(matchUrl) 
    If urlDecode is Nothing Then 
     Throw New Exception("Empty urlDecode.") 
    End If 
    For Each itm As DataGridViewRow In DataGridView1.Rows 
     If itm.Cells(0).Value = urlDecode Then 
       exists = True 
       Exit For 
     End If 
    Next 

    If DataGridView1.Rows.Count > 0 AndAlso exists then 
     Continue For 
    Else 
     Dim anchor_txt As String = HttpUtility.HtmlDecode(StrpTags(match.Groups(2).Value)) 
     If urlDecode is Nothing Then 
      Throw New Exception("Empty anchor text.") 
     End If 
     DataGridView1.Rows.Add(New String() {HttpUtility.HtmlDecode(matchUrl), anchor_txt, "", "", "", True}) 
    End If  
Catch ex As Exception 
     ' Show the exception's message. 
     MessageBox.Show(ex.Message) 
End Try 
+0

我肯定matchurl返回一個正值。是的,每個循環都有2個,主要是檢查html頁面的所有鏈接,第二個檢查datagridview中的重複項。我確實檢查matchurl是否沒有進一步的代碼。我添加了Try catch,並且在添加Exit時發現重複+定義的字符串,因此它不會多次調用httputility htmldecode。 – JDoe

+0

我剛剛運行應用程序的更改,但它仍然返回了兩個錯誤。我在上面添加了更多的代碼,以便您可以更好地理解代碼。 – JDoe

+0

@JDoe,你是否嘗試在'urlDecode = HttpUtility.HtmlDecode(matchUrl)'處放置一個斷點。 urlDecode的價值是什麼?這是否正確並且如預期的那樣? –

相關問題