1.

Solve : VB .NET Code Stops Executing?

Answer»

I'm having an issue with my Visual Basic .NET code. I've never seen this before. I don't have any sort of threading, so it's just blowing me away. I'm using .NET Framework 4.5 and this is a WinForms app. My code is below, with comments indicating where I'm having issues with. I'm compiling for x86 architecture. I've tried using a WebBrowser HtmlDocument, a WebKit.DOM.Document object, and now using the HTML Agility pack. The objective of this application is to REPLACE the IMVU Silent Room Observer at http://www.imvu-e.com/products/sro/. I'm using Visual Studio 2012 Express. Please ask if you have a question. Thank you in advance!

Code: [Select] Friend Sub FetchRoomMeta(ByVal roomtag As String, Optional ByVal silent As Boolean = False)
If Not silent Then : Me.lblGettingRoomData.Visible = True : End If
roomtag = roomtag.Replace("http://", "").Replace("https://", "").Replace("www.", "").Replace("imvu.com/rooms/", "")
Dim r As New IMVURoom()
r.TagName = roomtag
r.URL = "http://www.imvu.com/rooms/" & r.TagName
Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(r.URL)
req.UserAgent = "IMVU-SROR/" & My.Application.Info.Version.ToString()
Dim res As Net.HttpWebResponse = req.GetResponse()
If r.Occupants IsNot Nothing Then
r.Occupants = New List(Of String)
End If
Application.DoEvents()
Dim enc As System.Text.Encoding = (IIf(res.ContentEncoding = "UTF-8", New System.Text.UTF8Encoding, New System.Text.ASCIIEncoding))
' -----> Line below is the last line to execute
Dim htbytes As Byte() = {} : res.GetResponseStream().Read(htbytes, 0, res.ContentLength) : Dim httext As String = enc.GetString(htbytes)
' -----> This line is never reached and never executes
Dim resp As New HtmlAgilityPack.HtmlDocument : resp.LoadHtml(httext) : r.Occupants.Clear()
r.FriendlyName = resp.GetElementbyId("rm_name_name").InnerHtml
r.LaunchURL = resp.GetElementbyId("join_link").Attributes("href").Value
r.MaxOccupants = Byte.Parse(resp.GetElementbyId("rm_participants").InnerHtml.Split("/")(1).Trim())
For Each n As HtmlAgilityPack.HtmlNode In resp.GetElementbyId("participant_table").FirstChild.NextSibling.FirstChild.ChildNodes
If n.Name = "tr" Then
r.Occupants.Add(n.FirstChild.InnerHtml)
End If
Next n
For i As Byte = 0 To Rooms.Count - 1 Step 1
If r.URL = Rooms(i).URL Then
Rooms.RemoveAt(i)
Rooms.Insert(i, r)
End If
Next i
If Not silent Then : Me.lblGettingRoomData.Visible = False : End If
End Sub
Code: [Select]Dim htbytes As Byte() = {} : res.GetResponseStream().Read(htbytes, 0, res.ContentLength) : Dim httext As String = enc.GetString(htbytes)
This will throw an ArgumentOutOfRangeException every time. Stream.Read() requires a buffer that is already the required size for the data you want to read, but htbytes is always empty.

I expect the exception is getting swallowed further up the stack, meaning the stack unwinds and it never get's further through the method. though copy-pasting a single method out of an obviously larger project leaves a lot to my imagination.Made changes, unable to UPDATE the first post to reflect the new code. Still have the issue, though initializing the array to (res.ContentLength - 1) because of 0-based arrays. Also attached full code file, though I fail to see the point. This may just be my foggy brain and stubbornness at work causing me so much trouble, that's why I ask for some slightly fresher eyes to look at it. Big fan by the way, BC_Programmer. Been surfing CH for a long time, seen you everywhere.

Code: [Select]Friend Sub FetchRoomMeta(ByVal roomtag As String, Optional ByVal silent As Boolean = False)
If Not silent Then : Me.lblGettingRoomData.Visible = True : End If
roomtag = roomtag.Replace("http://", "").Replace("https://", "").Replace("www.", "").Replace("imvu.com/rooms/", "")
Dim r As New IMVURoom()
r.TagName = roomtag
r.URL = "http://www.imvu.com/rooms/" & r.TagName
Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(r.URL)
req.UserAgent = "IMVU-SROR/" & My.Application.Info.Version.ToString()
Dim res As Net.HttpWebResponse = req.GetResponse()
If r.Occupants IsNot Nothing Then
r.Occupants = New List(Of String)
End If
Application.DoEvents()
Dim enc As System.Text.Encoding = (IIf(res.ContentEncoding = "UTF-8", New System.Text.UTF8Encoding, New System.Text.ASCIIEncoding))
Dim htbytes(res.ContentLength - 1) As Byte
res.GetResponseStream().Read(htbytes, 0, res.ContentLength)
Dim httext As String = enc.GetString(htbytes)
' -----> Previously never executed, executes now
Dim resp As New HtmlAgilityPack.HtmlDocument()
' -----> Now never executes
resp.LoadHtml(httext)
r.Occupants.Clear()
r.FriendlyName = resp.GetElementbyId("rm_name_name").InnerHtml
r.LaunchURL = resp.GetElementbyId("join_link").Attributes("href").Value
r.MaxOccupants = Byte.Parse(resp.GetElementbyId("rm_participants").InnerHtml.Split("/")(1).Trim())
For Each n As HtmlAgilityPack.HtmlNode In resp.GetElementbyId("participant_table").FirstChild.NextSibling.FirstChild.ChildNodes
If n.Name = "tr" Then
r.Occupants.Add(n.FirstChild.InnerHtml)
End If
Next n
For i As Byte = 0 To Rooms.Count - 1 Step 1
If r.URL = Rooms(i).URL Then
Rooms.RemoveAt(i)
Rooms.Insert(i, r)
End If
Next i
If Not silent Then : Me.lblGettingRoomData.Visible = False : End If
End Sub

[attachment DELETED by admin to conserve space]Question:
What does this mean?
Quote

..objective of this application is to replace the IMVU Silent Room Observer at http://www.imvu-e.com/products/sro/
Do you mean you want to compile a windows program to run on a web server?Regarding the code thing, In order to get anything I could actually test I had to basically guess about things like IMVURoom and Rooms. Looks like I guessed IMVURoom incorrectly (I created a class, when it is a structure in your original) but guessed Rooms right (List of IMVURoom). Luckily I was able to find the Agility pack right in NuGet so I then just had to staple a few controls onto the form and guess what their actual type was, but there were only 2 that I saw at the time.

After making the change and replacing my Class version of IMVURoom with the struct and initializing the byte array, it now seems to load the data up fine but crashes at the attempt to clear the Room occupants, since the list is nothing.

Fixing that, it crashes at the attempt to get the Element by the ID. looking at the Data result, it's cut off. Was it too short? So I used Response.length and doubled it in both places. Still cut off in the same location.

I was able to fix that by replacing that segment with a StreamReader and using it to Read to the End of the Stream. I'm uncertain as to why, specifically, that fixes it, though.

The bigger PROBLEM is that all the Elements you retrieve are going to be empty because they are intended to be populated by client-side javascript, which an HTML parser isn't going to run.

Here is the changed version of that function anyway. I don't know how you might fix the issue where the links and other information are filled out by Javascript code, though.

Code: [Select]Friend Sub FetchRoomMeta(ByVal roomtag As String, Optional ByVal silent As Boolean = False)
If Not silent Then : Me.lblGettingRoomData.Visible = True : End If
roomtag = roomtag.Replace("http://", "").Replace("https://", "").Replace("www.", "").Replace("imvu.com/rooms/", "")
Dim r As New IMVURoom()
r.TagName = roomtag
r.URL = "http://www.imvu.com/rooms/" & r.TagName
Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(r.URL)
req.UserAgent = "IMVU-SROR/" & My.Application.Info.Version.ToString()
Dim res As Net.HttpWebResponse = req.GetResponse()
If r.Occupants IsNot Nothing Then
r.Occupants = New List(Of String)
End If
Application.DoEvents()
Using sr As New StreamReader(res.GetResponseStream())
Dim httext As String = sr.ReadToEnd()
Dim resp As New HtmlAgilityPack.HtmlDocument
resp.LoadHtml(httext)
r.Occupants.Clear()
r.FriendlyName = resp.GetElementbyId("rm_name").InnerHtml
r.LaunchURL = resp.GetElementbyId("join_link").Attributes("href").Value
r.MaxOccupants = Byte.Parse(resp.GetElementbyId("rm_participants").InnerHtml.Split("/")(1).Trim())
For Each n As HtmlAgilityPack.HtmlNode In resp.GetElementbyId("participant_table").FirstChild.NextSibling.FirstChild.ChildNodes
If n.Name = "tr" Then
r.Occupants.Add(n.FirstChild.InnerHtml)
End If
Next n
For i As Byte = 0 To Rooms.Count - 1 Step 1
If r.URL = Rooms(i).URL Then
Rooms.RemoveAt(i)
Rooms.Insert(i, r)
End If
Next i
End Using
If Not silent Then : Me.lblGettingRoomData.Visible = False : End If
End Sub


Upon doing a little more digging, I've discovered the Javascript variable on Line 668 (may vary) called roomInfo. If I can DIRECT the parser to the correct script element, extracting it should be a piece of cake. Thank you for your help! I'm going to mark the issue as solved.


Discussion

No Comment Found