Problem with programmatically submitting a form to web page

cmd_17

Member
Joined
Dec 7, 2008
Messages
13
Programming Experience
Beginner
Hello,

I'm an ASP.NET developer attempting to make my first Windows Forms application, and it's not going so well. :(

What I'm trying to do is programmatically fill in and submit an online form via a WebBrowser Control. I've researched this for hours already and found some example code, but nothing for my particular situation except the code found here: All About Microsoft.Net Technologies!: Programmatically input data on a form and click submit button using C#

I'm getting a NullReferenceException ("object reference not set to an instance of an object") for each of the two lines (which I tested separately) after WebBrowser1.Navigate(startSite). I've dealt with this error in ASP.NET, but I don't understand what the problem is in this particular context.

Here's my code:

------------------ Form1.vb ------------------
VB.NET:
Public Class Form1

    Const startSite As String = "http://www.somesite.com/somepage.aspx"

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        WebBrowser1.Hide()
        WebBrowser1.Navigate(startSite)
        WebBrowser1.Document.GetElementById("TextBox1").SetAttribute("Text", TextBox1.Text)
        WebBrowser1.Document.GetElementById("Button1").InvokeMember("click")

    End Sub
End Class

------------------ somepage.aspx ------------------

(some code omitted for brevity)

VB.NET:
<form id="form1" runat="server">
    <div>
        Enter your email:<br />
        <br />
        <asp:TextBox ID="TextBox1" runat="server" Text=""></asp:TextBox><br />
        <br />
        <asp:Button ID="Button1" runat="server" Text="Submit" /></div>
    </form>

I'd like the user to enter their email into a TextBox on Form1, press a button, and have an invisible WebBrowser navigate to the desired page and submit the form.

Any help with this would be greatly appreciated. Thanks in advance.
 
It is too soon to do anything right after the Navigate call, after that a lot happens with the browser. I'm sure you've witnessed anything from short to long delays before a document display when you are browsing the internet, also called "load time". What happens is that the browser connects to the other site and request a document, which it download and parses the content for, any other resources specified in the document source like script files, style sheets and images is downloaded, things are finally rendered to the combination of elements that displays in the browser window. The Navigate call does not block and wait until all this is done before returning, it returns immediately and will notify clients like you about changes in the browser state using events. What you have to do is to listen to the DocumentCompleted event, here you must check the browsers ReadyState property and see that it reports "Complete" before you attempt to access the Document tree programmatically.
 
Thanks for your helpful reply, John. It sounds like I need to do some more reading on the WebBrowser Control. :)
 
It turns out that the task is easier to accomplish with an HttpWebRequest. The working code, for anyone who's interested, is as follows:

VB.NET:
Public Class Form1

    Const postPage As String = "http://www.somesite.com/cgi-bin/whatever.cgi"

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        SubmitForm()
    End Sub

    Private Sub SubmitForm()
        Dim headerVars As String = "email=" & TextBox1.Text & "&item2=value2&item3=value3"
        Dim bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(headerVars)
        Dim req As HttpWebRequest = DirectCast(WebRequest.Create(postPage), HttpWebRequest)
        req.Method = "POST"
        req.ContentType = "application/x-www-form-urlencoded"
        req.ContentLength = bytes.Length

        Using requestStream As Stream = req.GetRequestStream()
            requestStream.Write(bytes, 0, bytes.Length)
        End Using

        Using response As HttpWebResponse = DirectCast(req.GetResponse(), HttpWebResponse)
            If response.StatusCode <> HttpStatusCode.OK Then
                Dim message As String = String.Format("POST failed. Received HTTP {0}", response.StatusCode)
                Throw New ApplicationException(message)
            Else
                MessageBox.Show("Success!")
            End If
        End Using
    End Sub

End Class

References:

this.Reflect() | Automated Form Posting with .NET / ASP.NET's CURL

Sending XML via HttpWebRequest - microsoft.public.dotnet.languages.csharp | Google Groups
 
Back
Top