Web Request Get Response fails on second try - vb.net

I wrote a program that searches for a user name on a web site and downloads the their main html page, finds the link to the next page and downloads that and so on. When I run the program the first time the get response for the search works correctly and the get response for downloading all of html pages works correctly. However, when I do a second search the get response fails for the search. I thought that maybe it was the server only allowing so many searches in a time period but it isn't that. When I close my program and run it again everything works fine again. Why does the get response fail on any attempts besides the initial one? You can't define a web request as new and their seems to be no way of closing a web request once it gets a response to free up resources. Is it because I run the whole process in a background worker? I don't know what's wrong. I always could do as many searches as I wanted to just yesterday...
Here's my code for the search form:
Private Sub FormSearch_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'if the user name is empty then initialize it
If My.Settings.UserName = "" Then
My.Settings.UserName = ""
End If
'if the current url is empty then initialize it
If My.Settings.CurrentURL = "" Then
My.Settings.CurrentURL = ""
End If
My.Settings.Save()
End Sub
Private Sub TextBoxUserName_TextChanged(sender As Object, e As EventArgs) Handles TextBoxUserName.TextChanged
'if the text length of the text box is greater then zero
If TextBoxUserName.TextLength > 0 Then
'enable the search button
ButtonSearch.Enabled = True
Else
'disable the search button and set focus on the text box
ButtonSearch.Enabled = False
TextBoxUserName.Focus()
End If
End Sub
Private Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
'trim the text box of any spaces
My.Settings.UserName = Trim(TextBoxUserName.Text)
'if the user name is not equal to null
If My.Settings.UserName <> "" Then
'set the current url and test if it exists
My.Settings.CurrentURL = "*url here*"
If URLExists(My.Settings.CurrentURL) = True Then
'save the settings
My.Settings.Save()
'return ok for the dialog result and close the form
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
Else 'cannot find the account
'set the text box text to null and set focus on it
TextBoxUserName.Text = ""
TextBoxUserName.Focus()
End If
End If
End Sub
Private Function URLExists(url As String) As Boolean
'create a new uri
Dim uriURL As New Uri(url)
'create a new web request of the uri
Dim wrRequest As WebRequest = WebRequest.Create(uriURL)
'set the web request timeout and method
wrRequest.Timeout = 30000
wrRequest.Method = "GET"
'create a new web response
Dim wrResponse As WebResponse
Try
'if the response succeeds then return true
wrResponse = wrRequest.GetResponse
Return True
Catch ex As Exception 'the response failed so return false
LabelMessage.Text = ex.Message
Return False
End Try
End Function

Related

How to refresh a datagrid on a parent form, from a child form

on frmBrands there a dgBrands that gets it's data in subLoadDgBrands. on frmBrand you can add a record to the dtBrands when you fire the btnSave_Click eventhandler. that same event handler also calls frmBrands.subLoadDgBrands however it does not refresh the dg that is displayed. I need it to refresh the dg on frmBrands when you finish the save procedure on frmBrand, as i only want to refresh if the save was succesfull, and for a different form i need to pass back an integer to that sub
Here's the relevant code
```VB
Public Class frmBrands
Friend Sub subLoadDgBrands()
dtBrands = fnGetBrand(0) 'Go get the data for the DataGridView
dgBrands.DataBindings.Clear()
dgBrands.DataSource = Nothing
dgBrands.Rows.Clear()
dgBrands.Columns.Clear()
If dtBrands IsNot Nothing Then
dgBrands.DataSource = dtBrands
dgBrands.Refresh()
subFormatDgBrands()
End If
End Sub
End Class
```
This event handler needs to refresh the datagrid on the instance of frmBrands that this form was opened through
```VB
Public Class frmBrand
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
'intID is passed by parent form = intBrand_ID
'intSupplier_ID is declared at the top of the form and set correctly by event handler
Dim intResult As Integer = 0
Dim strMessage As String = ""
Dim strBrandName As String = txtBrand.Text
'string builder that checks if the important fields are filled in
If strBrandName = "" Then 'if there is nothing written in str
If strMessage = "" Then 'and if the error message is empty
strMessage = "Please provide a brand name" 'then add the error message to the string
Else 'if the error message isn't empty '
strMessage &= "and brand name" 'then add str to the message
End If
End If
If intSupplier_ID < 1 Then 'if there is a 0 or negative ID selected, can also use cboSupplier.selectedValue
If strMessage = "" Then 'and if the error message is empty
strMessage = "Please provide a supplier" 'then add the error message to the string
Else 'if the error message isn't empty
strMessage &= "and supplier" 'then add "Title" to the message
End If
End If
'save string checker
If strMessage <> "" Then 'if there is something in the message
MsgBox(strMessage) 'display it
Else 'if there's nothing in the message
intResult = fnSaveBrand(intID,
intSupplier_ID,
strBrandName) 'We can save
'Additional logic loop that gives some feedback if it isn't saved
If intResult < 1 Then 'feedback number if the save wasn't succesfull
MsgBox("ID fault") 'Will let the user know it didn't save
Else 'the save was succesfull
**frmBrands.subLoadDgBrands()** 'Needs to refresh the datagrid on the instance of frmBrand**s** that this form was opened through
Me.Close() 'then it closes the form
End If
End If
End Sub
End Class
```
If you want to reflect the changes even frmBrand is still open, make subLoadDgBrands as Public then after your insert query was executed, add this
Dim _frmBrands As frmBrands = TryCast(Me.Owner, frmBrands)
_frmBrands.subLoadDgBrands()
If you want to reflect the changes right after the frmBrand was close, then replace Me.Close with Me.DialogResult = Windows.Forms.DialogResult.OK. Then in your code for opening frmBrand use
Using frmBrand As New frmBrand()
frmBrand.ShowDialog(Me)
If frmBrand.DialogResult = Windows.Forms.DialogResult.OK Then
subLoadDgBrands()
End If
End Using

Folder Browser Replacement

I want to be able to add multiple download links and for them to go into a single folder which is selected by the user in a Folder Browser Dialog
The code you see below works great except only for a single file. I have tried changing all 'savefiledialog1' to 'folderbrowserdialog1' instead. However this leads to me clicking download and nothing happening even if only a single link is entered.
Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
If (SaveFileDialog1.ShowDialog() = DialogResult.OK) Then
txtSave1.Text = SaveFileDialog1.FileName
btnDownload.Enabled = True
End If
End Sub
' ------------ DOWNLOADING SECTION ------------
Private WithEvents HTTPCLIENT As WebClient
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles
btnDownload.Click
btnDownload.Enabled = False
txtSave1.Enabled = False
btnBrowse.Enabled = False
btnDownload.Enabled = False
HTTPCLIENT = New WebClient
Dim Download As String
Download = Links(i)
Dim User = Environment.UserName
Dim Save As String = txtSave1.Text
Try
HTTPCLIENT.DownloadFileAsync(New Uri(Download), Save)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
I expected the folder browser dialog to just be a general save path where the file being downloaded is placed into that folder, however I am given an error.
The code above works but only for a single file.
I have code that can retrieve the download name and extension which I plan to add to the path once i figure this part out.
You can use the FolderBrowserDialog. Once you get the path, you combine it with each filename you will download. Use System.IO.Path.Combine()
Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
Using fbd As New FolderBrowserDialog()
If fbd.ShowDialog() = DialogResult.OK Then
txtSave1.Text = fbd.SelectedPath
btnDownload.Enabled = True
End If
End Using
End Sub
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles btnDownload.Click
Try
btnDownload.Enabled = False
txtSave1.Enabled = False
btnBrowse.Enabled = False
btnDownload.Enabled = False
Dim exceptionMessages As New List(Of String)
Using client = New WebClient()
' configure client here as needed i.e. add Credentials
For Each link In Links
Try
client.DownloadFileAsync(New Uri(link), Path.Combine(txtSave1.Text, link))
Catch ex As Exception
exceptionMessages.Add(ex.Message)
End Try
Next
End Using
If exceptionMessages.Any() Then MessageBox.Show($"Exception{If(exceptionMessages.Count > 1, "s", "")}: {String.Join(Environment.NewLine, exceptionMessages)}")
Finally
txtSave1.Enabled = True
btnBrowse.Enabled = True
btnDownload.Enabled = True
End Try
End Sub
Note that I will not post an answer with IDisposable objects without Using (in most cases) so FolderBrowserDialog and WebClient are both in Usings. You may need to add additional configuration to the WebClient before downloading.
Also, you probably don't want a separate message for each Exception, if any. So the messages can be cached and shown all at once.
I inserted a Finally for you to set control states back to default when done. This is up to you.
Lastly, the work is being done on a UI thread as evidenced by it being one inside the button click handler. You should move it off the UI even though you aren't blocking. This is outside the scope of the question.

Have to Click Form To Give Focus

I have a main form with buttons that open a custom message box form. It works fine if it's just a message and the user just needs to click OK. But if the answer to that message box is important, like "Are you sure you want to delete this file?" I use a while loop to wait for the user to respond and once they do then a flag is set from false to true and the response is recorded.
For some reason any response that uses a while loop to wait is causing the message box form to not have focus after being called. Requiring the user to first click on the form, and then click on OK.
So far I've tried using form.Activate() instead of form.Show(), as well as calling Application.DoEvents() inside the while loop since I believed the while loop was taking focus away from the message form immediately after being called. Neither solved the issue.
Code from a message box that works as intended:
If cmbLoadProgram.SelectedItem = "" Then
frmMessageBox.lblHeader.Text = "Set-Up"
frmMessageBox.lblMessageText.Text = "No Program Selected!"
frmMessageBox.Show()
Exit Sub
End If
Code from a message box that needs to be clicked twice:
If btnGetHexStart.Visible = False And cmbStartCondition.SelectedItem = "Pixel" Then
frmMessageBox.lblHeader.Text = "Hex Set-Up"
frmMessageBox.lblMessageText.Text = "Reset Hex Code Data?"
frmMessageBox.Show()
Me.Hide()
While Flag = False
If frmMain.OKCancel = "OK" Then
btnGetHexStart.Visible = True
btnGetHexStart.Enabled = True
btnGetHexStart.PerformClick()
Flag = True
End If
frmMain.delay(20)
End While
End If
I'm wanting both options to only need to be clicked once in order to confirm or cancel the action. Instead of the while loop questions needing to be clicked twice.
This just an idea from me, just how to open msgboxform, here we need MessageForm and one module1, for example:
Public Class MessageForm
'You can assign any variable to show any data in messageform display
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
theResult = MsgBoxResult.Ok
Me.Close()
Me.Dispose()
End Sub
Private Sub bttcancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttcancel.Click
theResult = MsgBoxResult.Cancel
Me.Close()
Me.Dispose()
End Sub
End Class
Module Module1
Public theResult As MsgBoxResult
'You can add some parameter here to submit to MessageForm
Public Function myMessageBox() As MsgBoxResult
myMessageBox = MsgBoxResult.Cancel
MessageForm.ShowDialog()
myMessageBox = theResult
End Function
End Module
and then you can call the myMessageBox anywhere like this:
'if myMessageBox procedure have parameter, apply the paramters too
dim myRslt = myMessageBox()
You don't need to create a form,You can use DialogResult and MessageBox.Show, code:
Dim Result As DialogResult = MessageBox.Show("Set-Up" & vbCrLf & "No Program Selected!", "Warning", MessageBoxButtons.OKCancel)
If Result = DialogResult.OK Then
ElseIf Result = DialogResult.Cancel Then
End If

Message box on close only show when text is changed

So I take no credit to the following code as it was given to me by another fellow user and don't get me wrong it works great but now I only Want the message box to show when text is changed in textboxes and if all text boxes are empty to just close the app when the X is clicked.
Any help is appreciated!
'Creates _handle as boolean
Private _handle As Boolean = True
Private Sub MainWindow_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
'Creates a messagebox to ask if the user wants to exit the application or no. If yes application closes, if no then application stays open
If _handle = True Then
e.Cancel = True
Dim result = MessageBox.Show("Are you sure you want to exit?", "Exit", MessageBoxButton.YesNo, MessageBoxImage.Question)
If (result = MessageBoxResult.Yes) Then
_handle = False
Environment.Exit(0)
End If
End If
End Sub

Using Windows Forms to open a browser and call a Javascript function

I'm new to this so please bear with me. I am using a VB.NET (2.0) Windows Forms application.
On Form_Load(), I open up IE browser, which then navigates to a particular URL with a login form. It passes the u/n and p/w values to this form and gets the button id and calls the click function on it, causing the browser to redirect to the web site as a user. It then executes a script on that page, which displays a bulk upload control.
I want to be able to get/set the value in the text box on this page.
'-->>> theTextBox = Nothing. After executing the script, the bulk update div is 'created in the page by the script. If we do a View Source, we can see an element with ID as 'TXT_UPLOAD as below.
'INPUT type="TEXT" id="TXT_UPLOAD" size="78" onblur="checkFileType(this,this.value, 'true)"
Here is my code:
Dim IE As New Object
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim URL As String = "http://someurl.com/"
Try
IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate("https://someurl.com/Login.aspx?")
Threading.Thread.Sleep(3000)
WaitUntil(IE.Document)
IE.Document.getElementById("tb_login").value = "username"
IE.Document.getElementById("tb_password").value = "password"
Dim theButton
theButton = IE.Document.getElementById("btn_login")
theButton.Click()
Threading.Thread.Sleep(5000)
WaitUntil(IE.Document)
IE.Document.parentWindow.execScript("parent.showApplication('Bulk Update', 712030600,-1,712000000,1);")
Dim theTextBox
theTextBox = IE.Document.getElementById("TXT_UPLOAD")
theTextBox.Focus()
Debug.Print(theTextBox.value)
theTextBox.Value = "C:\NV\CV\CLWR_NA_CHG_UPLOAD_2014313.csv"
IE.Document.parentWindow.execScript("parent.logOff();")
Catch ex As Exception
MsgBox(ex.ToString)
Threading.Thread.Sleep(5000)
WaitUntil(IE.Document)
IE.Document.parentWindow.execScript("parent.logOff();")
End Try
IE = Nothing
'IE.kill()
'IE.Quit()
End
End Sub