I have a windows form with a webbrowser control. Using this control, I need login to a website, and get and post data.
The login part will remain manually because various headers and cookies and created and stored.
However, is it possible to use the control to send post/get requests?
I do something like this and it works for me.
string postData = "value1=" + 1 + "&value2=" + 2 + "&value3=" + 3;
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
byte[] bytes = encoding.GetBytes(postData);
string url = "http://www.domain.com/addSomething";
webBrowser1.Navigate(url, string.Empty, bytes, "Content-Type: application/x-www-form-urlencoded");
I hope it is of help.
Related
I'm trying to scrape a web page hosted on a device on my network. I've done this dozens of times with other model devices on the same network. When I browse to the page in IE or Chrome, it's formatted properly and I see the source I'm expecting.
However, when I try to read the response stream in .Net or try running it in Fiddler, I'm given source for what looks like Javascript and session generating scripting rather than the numbers I care about.
I think this page is now hitting a javascript powered landing page, calling back to the printer, then formatting and outputting back into my browser. I think my difference is that calls from inside of Fiddler and .Net GetResponseStream() calls aren't letting the javascript do what it needs to to get all of the data.
Sample
WebRequest ConReq = WebRequest.Create(consumablePage);
WebRequest UseReq = WebRequest.Create(usagePage);
ConReq.Timeout = 15000;
UseReq.Timeout = 20000;
WebResponse ConResp = ConReq.GetResponse();
WebResponse UseResp = UseReq.GetResponse();
Stream Constream = ConResp.GetResponseStream();
StreamReader Consr = new StreamReader(Constream);
Stream Usestream = UseResp.GetResponseStream();
StreamReader Usesr = new StreamReader(Usestream);
string conRead = Consr.ReadToEnd();
string useRead = Usesr.ReadToEnd();
At the end, conRead and useRead both contain:
"<html>\r\n<head>\r\n<script language=\"JavaScript\" type=\"text/javascript\">\r\n<!-- \r\nfunction SetCookie ( inCookieName, inCookieValue, inCookieExpiration)\r\n{\r\n\tdocument.cookie\t\t= inCookieName + \"=\" + escape( inCookieValue ) + \r\n\t\t\t\t\t\t\t( inCookieExpiration ? \"; expires=\" + getExpiryDate(inCookieExpiration) : \"\" ) + \r\n\t\t\t\t\t\t\t\t\"; path=/\";\r\n}\r\n\r\nfunction getExpiryDate(nodays)\r\n{\r\n\tvar UTCstring;\r\n\tToday = new Date();\r\n\tnomilli=Date.parse(Today);\r\n\tToday.setTime(nomilli+nodays*24*60*60*1000);\r\n\tUTCstring = Today.toUTCString();\r\n\treturn UTCstring;\r\n}\r\n\r\nfunction generateSessionID()\r\n{\r\n\tvar \tgetTcpIpAddr = \"10.210.13.138\";\r\n\tvar SESSION_ID =\"SESSION_ID\";\r\n\tvar ipArray = getTcpIpAddr.split(\".\");\r\n\tvar ip = parseInt(ipArray[0], 10) + parseInt(ipArray[1], 10) + parseInt(ipArray[2], 10) + parseInt(ipArray[3], 10);\r\n\tvar d = new Date();\r\n\tID = parseInt((d.getMilliseconds()*ip)/32, 10);\r\n\tSetCookie(SESSION_ID, ID,365);\t//365 - expiry date is 1 year\r\n\twindow.location=window.location.toString();\r\n}\r\n-->\r\n</script>\r\n</head>\r\n<body onLoad=\"generateSessionID()\">\r\n</body>\r\n</html>\r\n"
This picture is an example of a Fiddler GET, and an IE instance of the same page. Note the Fiddler response is only 1075K and the IE response is 6602K.
How can I get a fully parsed response stream back in .Net?
I am new here and I hope someone can help me. I try to connect to twitch.tv I am trying to get an oauth2 authentication on twitch.tv with a small C# program. I am using the twitch.tv authentication request. Here is my C# code:
var loginURL = "https://api.twitch.tv/kraken/oauth2/authorize?
response_type=code&"+
client_id="+ clientID+"
"&redirect_uri=http://localhost&"+
"state=TWStreamingStateAuthenticated";
this.richTextBox1.Text = loginURL;
string code = get_DownLoadString(loginURL);
this.richTextBox1.Text = code;
This is the part, which does not work. It gives me the Error 400: Bad Request.
WebRequest request = WebRequest.Create("https://api.twitch.tv/kraken/oauth2/token");
request.Method = "POST";
string postData = "client_id=" + clientID +
"&client_secret=" + clientSecret +
"&grant_type=authorization_code" +
"&redirect_uri=http://localhost" +
"&code=" + code +
"&state=TWStreamingStateAuthenticated";
ASCIIEncoding encoding = new ASCIIEncoding();
postData = HttpUtility.UrlEncode(postData);
byte[] byteArray = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream datatream = request.GetRequestStream();
datatream.Write(byteArray, 0, byteArray.Length);
datatream.Close();
WebResponse respone = request.GetResponse();
MessageBox.Show(((HttpWebResponse)respone).StatusDescription);
I hope someone can help me.
And here is the Get_DownloadString(string URL) Method.
private static string get_DownLoadString(string URL)
{
try
{
string temp = (new WebClient().DownloadString(URL));
return temp;
}
catch (WebException)
{
return null;
}
}
This code doesn't look right to me:
string postData = "client_id=" + clientID +
"&client_secret=" + clientSecret +
"&grant_type=authorization_code" +
"&redirect_uri=http://localhost" +
"&code=" + code +
"&state=TWStreamingStateAuthenticated";
ASCIIEncoding encoding = new ASCIIEncoding();
postData = HttpUtility.UrlEncode(postData);
byte[] byteArray = encoding.GetBytes(postData);
// ...
You are URL-encoding the entire post-data string. This has the effect of converting the & and = signs in the post data to %26 and %3d respectively. When the remote server receives this data, it will scan through it looking for the & and = signs in order to separate out the parameter names and values. Of course, it won't find any, so it will assume you have one big parameter name with no value. The server is probably expecting values for each of the six parameters you are attempting to send, but seeing values for none of them, and this may be why you are getting a 400 Bad Request error.
Instead of URL-encoding the whole string, URL-encode parameter values that may contain characters other than letters and numbers. I would try the following instead:
string postData = "client_id=" + HttpUtility.UrlEncode(clientID) +
"&client_secret=" + HttpUtility.UrlEncode(clientSecret) +
"&grant_type=authorization_code" +
"&redirect_uri=" + HttpUtility.UrlEncode("http://localhost") +
"&code=" + HttpUtility.UrlEncode(code) +
"&state=TWStreamingStateAuthenticated";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byteArray = encoding.GetBytes(postData);
// ...
This way, the remote server will still see the & and = characters, and so will be able to pull out the parameter names and values. Because we've URL-encoded the client ID, client secret, URL and code, any characters they contain that may have meaning in a URL will not have that meaning and will be received by the remote server as intended.
Also, if you are still getting a 400 Bad Request error response, try reading the contents of the response stream, obtained by calling GetResponseStream() on the response. Often that will contain a message that will help you figure out what's gone wrong.
Having had a closer look at your code, it seems you have a misunderstanding about how OAuth authentication works. Your getDownload_String method will not get the access code you want, it will only get the HTML text of a Twitch login page.
This is how OAuth authentication works:
Your app sends the user to a login URL, to allow the user to log in to Twitch.
In the web browser, the user then enters their login credentials and submits the page to Twitch.
The Twitch API then responds by redirecting the user's web browser to the redirect URL, with a code appended. Your web app then reads this code out of the URL.
If your code is in a web app it will be able to respond to the URL redirected to in step 3. Alternatively, you may be able to use a WebBrowser control (Windows Forms, WPF) to handle the Twitch login, and handle a Navigating event. If the URL being navigated to begins with the redirect URL, grab the code out of the URL, cancel the navigation and hide the login web-browser control.
The presence of what appears to be a RichTextBox control, along with your comment about your code being a 'small C# application', makes me think that your code is a Windows Forms or WPF application. If this is the case, then you will need to either:
use a WebBrowser control as I described above,
replace your WinForms/WPF app with a web app, or
get in contact with Twitch to request the use of the password flow (which appears not to require a redirect), and use that instead.
I'm not very good with any networking type of things (as far as C# goes) but I need to post data (not get!) to a web url and then return what it outputs.
So far I'm using this for post and determining if it's logged in or not.
//credentials
string username = textBox1.Text;
string password = textBox2.Text;
using (WebClient client = new WebClient())
{
byte[] data = Encoding.Default.GetBytes("username="+username+"&password="+password);
client.Headers["Content-Type"] = "application/Json";
try
{
var response2 = client.UploadData(base_url + "/users/authenticate", "POST", data);
MessageBox.Show(Encoding.Default.GetString(response2));
}
catch { }
}
Note: Error I'm getting is 400 bad request. Any ideas?
Looking at the vine code, I would say you need to send it JSON data instead of URL data. With something simple like that you can just write the string.
String jsonData = "{\"username\": \"" + username + "\", \"password\": \"" + password + "\"}";
Updated to add encoding and be more strict with JSON data
PHP's JSON decoder wants UTF-8 encoded data, so also change the encoding line to
byte[] data = Encoding.UTF8.GetBytes(jsonData);
I have, in my silverlight application, a call to a aspx page, to create and register a txt file on a directory.
Uri ub = (new Uri(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&id=" + this.Id));
if (HtmlPage.IsPopupWindowAllowed)
{
HtmlPopupWindowOptions opt = new HtmlPopupWindowOptions();
HtmlPage.PopupWindow(ub, "file", opt);
}
else
{
HtmlPage.Window.Navigate(ub);
}
I have to go trough my aspx page to generate my txt file, because silverlight don't allow it.
The problem here is, a popup will appear, or the page will load the new uri.
What I want is call the code inside the asp only(which works perfectly), without loading the uri.
Is there a way to do this?
Edit : After DGibbs answer, there is another question now :
WShy can't I use GetResponse() in there?
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri
(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&idPocedure=" + itmProcedure.IdProcedure));
string response = new System.IO.StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd();
Here a little answer : Silverlight is asynchrnous, so, we can't call GetResponse who is synchronous.
So, the best way to call my aspx page, is to use WebClient found here
You could just use WebRequest:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri
(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&id=" + this.Id));
string response = new System.IO.StreamReader(req.GetResponse()
.GetResponseStream()).ReadToEnd();
I'm use Asp.Net Mvc 4
www.hostname.com to my site from my report.hostname2.com
send and receive data to move directly to that address by the string bi codebehind.
querysstring not, because sending a very long string
I mean rapor.coskunoglu.net/Pdf address to send string data to move directly to
that address
PDF of the screen to make it appear so.
How can I do this?
Thank you, take it easy.
I'm sorry, my english is not good.
EDIT0:
I want to use POST.
sb -> my StringBuilder.
byte[] bytt = Encoding.UTF8.GetBytes(sb.ToString());
WebRequest wr = WebRequest.Create("http://report.hostname2.com/Pdf");
wr.ContentType = "application/x-www-form-urlencoded";
wr.ContentLength = bytt.Length;
wr.Method = "POST";
Stream st = wr.GetRequestStream();
st.Write(bytt, 0, bytt.Length);
st.Close();
After you send the POST I want to go to report.hostname2.com.
Did you see this my job?
One way to achieve that is to store the data you want to transmit into some commonly shared database between the two sites and then simply send an id to the other site as a query string so that it could retrieve the data. If you cannot use a shared database then all that's left is standard HTTP protocol means:
GET - query string - impractical in your case if the data is large
POST - generate a form and then submit this form to the remote site - could be a good solution for your case because you are not limited in size
Alternatively you could use a WebClient to POST some data:
StringBuilder sb = ... the data to send
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "data", sb.ToString() }
};
byte[] result = client.UploadValues("http://report.hostname2.com/Pdf", values);
}
And then on the remote site you could read the data POST parameter from the request.