WebRequest : execute a button

P

Paul

Hello,

I tried to execute a button on an aspx webpage using WebRequest, but it
failed.
When posting data as if I did a login (see code), I just receive the
login page, instead of the page I should get after login.
The button I tried to 'push' (by adding &login=Login in de posted data,
where login is the name of the login button - I verified this data by
capturing the data of a request using a webbrowser) has not executed.

This is how I proceeded :

- First I requested the webpage in the standard way when you use
WebRequest :

string uri = @"http://localhost/Login.aspx";
WebRequest req = WebRequest.Create(uri);
WebResponse response = req.GetResponse();
Stream respstream = response.GetResponseStream();
StreamReader reader = new StreamReader(respstream, Encoding.ASCII);
string resphtml = reader.ReadToEnd();

- From the response I used regex to obtain the viewstate that I will
use in the second request where I just want to push a button on the
loginpage :

string html = resphtml.Replace("\n", " ");
Regex r = new Regex("<input[\\t ]+type=\"hidden\"[\\t
]+name=\"__VIEWSTATE\" value=\"(?<viewstate>[^\"]+)\"");
Match m = r.Match(html);
string viewstate = "";
if (m.Success) { viewstate = m.Groups["viewstate"].Value; }

- I prepare the string I will post; notice "login=Login" by which I
pushed the button. I also did an url encoding (space to +, strange
chars to %xx) :

string requeststr =
string.Format("__VIEWSTATE={0}&name=myname&pwd=notofyourbusiness&login=Login",viewstate);
string requrlencoded = UrlEncoder.Encode(requeststr);

- Then a do a POST with the data in requeststr you see a little higher
:

req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] encodedBytes = Encoding.UTF8.GetBytes(requrlencoded);
req.ContentLength = encodedBytes.Length;

Stream requestStream = req.GetRequestStream();
requestStream.Write(encodedBytes, 0, encodedBytes.Length);
requestStream.Close();

response = req.GetResponse();
respstream = response.GetResponseStream();
reader = new StreamReader(respstream, Encoding.ASCII);
resphtml = reader.ReadToEnd();
respstream.Close();
response.Close();

I also tried it with new objects, instead of reusing the objects of the
first request (same result).

Instead of executing the login button I just receive the login page
again, as if I requested that page without the POSTed data.

Has anyone tried something similar or has anybody suggestions about
what I did wrong ?

Thanks for any help,

Paul
 
N

Nicholas Paldino [.NET/C# MVP]

Paul,

Do you have access to the code for the site you are trying to access?
It might be easier for you to expose a web service from that website, and
consume it in your code. The amount of code that you are using which is
dependent on things you shouldn't have to deal with (parsing viewstate out
of the page, for instance) is staggering.

Exposing a web service, if possible, would be a much, much better
solution.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Paul said:
Hello,

I tried to execute a button on an aspx webpage using WebRequest, but it
failed.
When posting data as if I did a login (see code), I just receive the
login page, instead of the page I should get after login.
The button I tried to 'push' (by adding &login=Login in de posted data,
where login is the name of the login button - I verified this data by
capturing the data of a request using a webbrowser) has not executed.

This is how I proceeded :

- First I requested the webpage in the standard way when you use
WebRequest :

string uri = @"http://localhost/Login.aspx";
WebRequest req = WebRequest.Create(uri);
WebResponse response = req.GetResponse();
Stream respstream = response.GetResponseStream();
StreamReader reader = new StreamReader(respstream, Encoding.ASCII);
string resphtml = reader.ReadToEnd();

- From the response I used regex to obtain the viewstate that I will
use in the second request where I just want to push a button on the
loginpage :

string html = resphtml.Replace("\n", " ");
Regex r = new Regex("<input[\\t ]+type=\"hidden\"[\\t
]+name=\"__VIEWSTATE\" value=\"(?<viewstate>[^\"]+)\"");
Match m = r.Match(html);
string viewstate = "";
if (m.Success) { viewstate = m.Groups["viewstate"].Value; }

- I prepare the string I will post; notice "login=Login" by which I
pushed the button. I also did an url encoding (space to +, strange
chars to %xx) :

string requeststr =
string.Format("__VIEWSTATE={0}&name=myname&pwd=notofyourbusiness&login=Login",viewstate);
string requrlencoded = UrlEncoder.Encode(requeststr);

- Then a do a POST with the data in requeststr you see a little higher
:

req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] encodedBytes = Encoding.UTF8.GetBytes(requrlencoded);
req.ContentLength = encodedBytes.Length;

Stream requestStream = req.GetRequestStream();
requestStream.Write(encodedBytes, 0, encodedBytes.Length);
requestStream.Close();

response = req.GetResponse();
respstream = response.GetResponseStream();
reader = new StreamReader(respstream, Encoding.ASCII);
resphtml = reader.ReadToEnd();
respstream.Close();
response.Close();

I also tried it with new objects, instead of reusing the objects of the
first request (same result).

Instead of executing the login button I just receive the login page
again, as if I requested that page without the POSTed data.

Has anyone tried something similar or has anybody suggestions about
what I did wrong ?

Thanks for any help,

Paul
 
B

Bruce Barker

you don't urlencode the postdata, you urlencode each value

string.Format("__VIEWSTATE={0}&name={1}&pwd={2}&login=Login",
UrlEncoder.Encode(viewstate),
UrlEncoder.Encode(name),
UrlEncoder.Encode(pwd))

you don't want the "&" and "=" delimiters encoded. no special chars are
allowed in a value name.

note: the leading "__" in VIEWSTATE is a violation of W3C standards. don't
follow ms's example in your own field names.

-- bruce (sqlwork.com)


Paul said:
Hello,

I tried to execute a button on an aspx webpage using WebRequest, but it
failed.
When posting data as if I did a login (see code), I just receive the
login page, instead of the page I should get after login.
The button I tried to 'push' (by adding &login=Login in de posted data,
where login is the name of the login button - I verified this data by
capturing the data of a request using a webbrowser) has not executed.

This is how I proceeded :

- First I requested the webpage in the standard way when you use
WebRequest :

string uri = @"http://localhost/Login.aspx";
WebRequest req = WebRequest.Create(uri);
WebResponse response = req.GetResponse();
Stream respstream = response.GetResponseStream();
StreamReader reader = new StreamReader(respstream, Encoding.ASCII);
string resphtml = reader.ReadToEnd();

- From the response I used regex to obtain the viewstate that I will
use in the second request where I just want to push a button on the
loginpage :

string html = resphtml.Replace("\n", " ");
Regex r = new Regex("<input[\\t ]+type=\"hidden\"[\\t
]+name=\"__VIEWSTATE\" value=\"(?<viewstate>[^\"]+)\"");
Match m = r.Match(html);
string viewstate = "";
if (m.Success) { viewstate = m.Groups["viewstate"].Value; }

- I prepare the string I will post; notice "login=Login" by which I
pushed the button. I also did an url encoding (space to +, strange
chars to %xx) :

string requeststr =
string.Format("__VIEWSTATE={0}&name=myname&pwd=notofyourbusiness&login=Login",viewstate);
string requrlencoded = UrlEncoder.Encode(requeststr);

- Then a do a POST with the data in requeststr you see a little higher
:

req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] encodedBytes = Encoding.UTF8.GetBytes(requrlencoded);
req.ContentLength = encodedBytes.Length;

Stream requestStream = req.GetRequestStream();
requestStream.Write(encodedBytes, 0, encodedBytes.Length);
requestStream.Close();

response = req.GetResponse();
respstream = response.GetResponseStream();
reader = new StreamReader(respstream, Encoding.ASCII);
resphtml = reader.ReadToEnd();
respstream.Close();
response.Close();

I also tried it with new objects, instead of reusing the objects of the
first request (same result).

Instead of executing the login button I just receive the login page
again, as if I requested that page without the POSTed data.

Has anyone tried something similar or has anybody suggestions about
what I did wrong ?

Thanks for any help,

Paul
 
J

Joerg Jooss

Paul said:
Hello,

I tried to execute a button on an aspx webpage using WebRequest, but
it failed.
When posting data as if I did a login (see code), I just receive the
login page, instead of the page I should get after login.
The button I tried to 'push' (by adding &login=Login in de posted
data, where login is the name of the login button - I verified this
data by capturing the data of a request using a webbrowser) has not
executed.

This is how I proceeded :

- First I requested the webpage in the standard way when you use
WebRequest :

string uri = @"http://localhost/Login.aspx";
WebRequest req = WebRequest.Create(uri);
WebResponse response = req.GetResponse();
Stream respstream = response.GetResponseStream();
StreamReader reader = new StreamReader(respstream, Encoding.ASCII);
string resphtml = reader.ReadToEnd();

- From the response I used regex to obtain the viewstate that I will
use in the second request where I just want to push a button on the
loginpage :

string html = resphtml.Replace("\n", " ");
Regex r = new Regex("<input[\\t ]+type=\"hidden\"[\\t
]+name=\"__VIEWSTATE\" value=\"(?<viewstate>[^\"]+)\"");
Match m = r.Match(html);
string viewstate = "";
if (m.Success) { viewstate = m.Groups["viewstate"].Value; }

- I prepare the string I will post; notice "login=Login" by which I
pushed the button. I also did an url encoding (space to +, strange
chars to %xx) :

string requeststr =
string.Format("__VIEWSTATE={0}&name=myname&pwd=notofyourbusiness&login
=Login",viewstate); string requrlencoded =
UrlEncoder.Encode(requeststr);

As Bruce already pointed out, that's not going to work. You have to
encode all values of the query string individually, unless UrlEncoder
is meant to be a non BCL class which handles entire strings (unlike
HttpUtility.UrlEncode()).
- Then a do a POST with the data in requeststr you see a little higher
:

req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] encodedBytes = Encoding.UTF8.GetBytes(requrlencoded);
req.ContentLength = encodedBytes.Length;

Stream requestStream = req.GetRequestStream();
requestStream.Write(encodedBytes, 0, encodedBytes.Length);
requestStream.Close();

response = req.GetResponse();
respstream = response.GetResponseStream();
reader = new StreamReader(respstream, Encoding.ASCII);
resphtml = reader.ReadToEnd();
respstream.Close();
response.Close();

I also tried it with new objects, instead of reusing the objects of
the first request (same result).

You confuse objects with variables. For the sencond request, you reuse
your local variables, but have a new HttpWebRequest, a new
HttpWebResponse, and a new StreamReader.
Instead of executing the login button I just receive the login page
again, as if I requested that page without the POSTed data.

Has anyone tried something similar or has anybody suggestions about
what I did wrong ?

You're missing session management. Add a CookieContainer instance to
your HttpWebRequest to allow for cookie management and use it
throughout your session.

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top