HttpWebRequest with POST and GET at the same time - c#

I need to redirect a user to http://www.someurl.com?id=2 using a POST method.
Is it possible? If yes, then how?
Right now I have following and it forwards the POST data properly, but it removes the ?id=2:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.someurl.com?id=2");
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(postData);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
Response.Write(reader.ReadToEnd());
}
The reason I need both query string data -> ?id=2 and POST data is because I pass the query string to page in which javascript is going to be handling the query string data and .NET is going to work with data sent via POST method. The POST data that I am passing can be longer than maximum amount of characters that GET method allows, therefore I can't use only GET method... so, what are your suggestions?
More information:
I am writing a routing page, which adds some custom information to query string and then routes all of the data, old and new further to some URL that was provided. This page should be able to redirect to our server as well as to someone's server and it doesn't need to know where it came from or where it goes, it just simply needs to keep the same POST, GET and HEADER information as well as additional information received at this step.

No. There is no fathomable reason to mix POST and GET.
If you need to make parameters passed in with the request available to Javascript, simply POST them to the server, and have the server spit out the relevant information in a hidden field...
<input type="hidden" value="id=2,foo=bar" disabled="disabled" />
Simple as that.
Note: Disable the hidden field to exclude it from the subseqient POST, if there is one ;)

The problem i think that the problem could be that postData does not contain the id parameter as it is supplied through querystring.
Posted data is in the body of the request and querystring data is in the url.
You probably need to fetch the id from request.querystring to you postdata variable.

Given the extra information to your question, that you require to submit to an external source, what I believe you must do is process all of the data and return a form with hidden fields. Add some javascript to submit that form to the external URL immediately upon load. Note that you won't get file uploads this way, but you can appropriately handle POST and GET data.

As far as I know, it isn't possible to redirect with POST. Couldn't you simply pretend (internally handle as if) that the request was made to the page you want to redirect the user to?

The closest answer I've found to this problem is here, but it's not transparent to the user, therefore it's not good enough for me --> Response.Redirect with POST instead of Get?
If anybody has any other suggestions, please respond!

Try sending all of the data including the id in POST. Then when you are processing the data in C#, you can read the id variable in and write it back out to your webpage within a tag:
<script type="text/javascript">
id = <%=request_id%>
</script>
Then just make sure your javascript starts running after fully loaded with an onload() call and you're good to go.

What you are actually trying to do is redirect your POST data. May I ask why? I can't see any reason why you would want to do this if in fact both pages are on your servers.
What you should be doing is processing all of your POST data in script #1, and then redirecting to something like script2.aspx?id=234 where the ID 234 is in reference to the data in your database. You can then recall it later on script2 and dump all the data into Javascript variables for your client-side stuff to use.
Either way, something about this process sounds fishy to me. Mixing up your data processing client-side and server side is like mixing vodka and milk. It rarely works well. (But white russians sure are tasty!)

Actually I was able to achieve the desired result by mixing Javascript and Codebehind code. So, what I've done is in server side code I've built an entire web page like following:
var strForm = new StringBuilder();
strForm.Append("<form id=\"" + formId + "\" name=\"" + formId + "\" action=\"" + url + queryString +"\" method=\"POST\">");
foreach (string key in data)
{
strForm.Append("<input type=\"hidden\" name=\"" + key + "\" value=\"" + data[key].Replace("\"", """) + "\">");
}
strForm.Append("</form>");
And in addition to this form built on server side, I add a javascript code that submits the form I've just built.
var strScript = new StringBuilder();
strScript.Append("<script language='javascript'>");
strScript.Append("var v" + formId + " = document." + formId + ";");
strScript.Append("v" + formId + ".submit();");
strScript.Append("</script>");
strForm.Append("</form>");
So, what this code does, is as you see, the form action is an URL with query string parameters attached to it... but since the form method is POST, we submit the values we added as a hidden fields as POST parameters... So we end up submitting both POST and GET parameters.
Hope this solution will help somebody =)

Related

Cannot figure out how this jQuery code is working

So there is a camera taking images every couple seconds and storing those new images with new files names on the server. When a request is made to "mypage", server side the latest images are loaded up and returned in the response. The images subsequently being refreshed with this jQuery code:
(function($) {
$(function() {
var refreshInterval = 5; // Number of seconds between image refreshes
$('#deskshare-grid img').each(function() {
$(this).data('src', $(this).attr('src'));
});
function refreshImages() {
$.get('?r=' + Math.random(), function(response) {
$('#deskshare-grid img').each(function(index) {
$(this).attr('src', $(response).find('#deskshare-grid img').eq(index).attr('src'));
});
setTimeout(refreshImages, refreshInterval * 1000);
});
}
setTimeout(refreshImages, refreshInterval * 1000);
});
})(jQuery);
The jQuery code I shared works and that is great, I didn't write the code and I want to know how it works.
My mind is stuck on the fact that a request was made for the page, the most recent image was retrieved on the server using C# and those images are included in the response. When a more recent image is created, it has a new file name.
How can jQuery refresh the photo for a file name it does not know client side?
Particularly this part of the code is confusing me:
$.get('?r=' + Math.random(), function(response) {
What is the url request for this $.get? I see the network tab of my F12 tools showing the new image responses but I do not understand how an image with a different file name could be requested with jQuery.
UPDATE
The accepted answer is correct but I wanted to elaborate. This jQuery is requesting the entire page again. The HTML response contains new image urls from the server. jQuery is used to parse the response, get the latest image urls and than update the existing HTML content with those new image urls parsed out of the response. This way there is no page flicker by trying to just refresh the entire page.
It does get request to the same page, Math.random() is to make easier to view each request. When you make a request to ? that is the same page.
What is the url request for this $.get?
The first parameter in the $.get is a relative url. This means that the url it's trying to access will be something along the lines of www.yourdomain.com/whatever?r=.
The "?" indicates the start of a query string, the "r" is the start of the request variable and whatever follows the equal sign is the query itself. In this particular case the query is just a randomly generated number that is sent up to the server. Without seeing the server-side code it would appear as if the filename is generated on the client and sent up to the server in this manner, and is probably used to name the file then on the server-side then.
The $.get('?r=' + Math.random(), function(response) { could be this two things:
Its changing the URL as a trick to not to get cached content.
Is server side required as dummy or something that we don't really know.
I recommend to look at the request's and response's headers for each 5'' call.

c# httpclient POST request: cant send special characters

I have a program that should login to site, it uses POST requests, and all goes fine, until one of the values contain special character('%' for example).
captcha = "ABCDE" //all goes fine and well, server accept captcha
captcha = "ABC&%" //server dont accept captcha and return fail
//here is the bad part:
string request = "password=" + HttpUtility.UrlEncode(encpass, Encoding.UTF8) +
"&username=" + login + "&captcha_text=" + HttpUtility.UrlEncode(captcha, Encoding.UTF8);
Also, i ofcourse googled it, and checked all i could find. I though i need to "warn" server abaut encoding, so i added
request.Headers.TryAddWithoutValidation("Content-Type", #"application/x-www-form-urlencoded; charset=UTF-8");
but it still did not helped me.
Content types and way request should look like i get from Firebug, so if i can find some answers there - please point.
modify0: Also, i compared what my program send to server with browser request(using Firebug) and my request is completley same. Only difference - my request dont get accepted in values it contain special-characters.
modify1: Also, server have no problems handling special-characters when i check it in browser. For example it(browser) sent "K&YF82" as "captcha_text=K%26YF82"(same value in addres propereties and request body) and all worked fine. UrlEncode do same replacement, but in my program it doesnt get accepted by server.
SOLUTION:
{ password:"df464dsj", username:"username", captchaText:"ABC&%", remember_login:"false" }
insteat of
password=f2341f14f&username=username&captha...
Are you dealing with REST application??
If yes then send your post data in request body instead of query string.
Also have a look at the stack post at : Special characters pose problems with REST webservice communication

asp.net button onclick post to another page

I have a page in .Net that currently does some processing of info when a button is clicked. It posts back, updates some info and then redirects the user onwards.
What I want to do now is for this same button, when it's clicked, the info is updated but instead of a redirect it does a POST to another site. The reason being that this other site needs to read a bunch of data from the form I submit.
So, I know about the PostBackUrl property but that will stop the processing of the data that I need done.
So is there another way for me to be able to somehow combine both a postback that then becomes as POST to another site?
Or alternatively some way for me to be able to do the updates I need and then do a POST?
The suggested solutions all kind-of worked but the only one that actually did exactly what I needed it to was this one:
Link to SO answer
The reason the other answers above didn't work is that I was POSTing to a payment gateway and for whatever reason their system thought there was a problem with various missing fields in all solutions except the one I linked to. No idea why, I don't have access to their systems to know what they were actually doing.
In any case, thanks for all answers but have a look at the linked one if you're running into a similar issue.
if PostBack isn't absolutely needed, you can actually send them in the request query itself.
You can do a POST from codebehind, you can find details in this answer Redirect to another page using Post method from Code behind
If I got your question right I think you will need to get all the form data from Request.Form and make a HttpWebRequest to the other site:
string url = "http://anothersite.com/";
// create post data
StringBuilder postDataBuilder = new StringBuilder();
foreach (var key in this.Request.Form.AllKeys)
{
postDataBuilder.AppendFormat("{0}={1}&", this.Request.Form[key]);
}
string postData = postDataBuilder.ToString();
// create the web request for the POST
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = postData.Length;
// add the post data
using (StreamWriter requestStream = new StreamWriter(webRequest.GetRequestStream()))
{
requestStream.Write(postData);
}
Hope this helps!

When Web Browsing from code, how do you send information to an <input .* type="Submit"> and retrieve the resulting link?

Similar threads may be:
How do I programmatically send information to a web service in C# with .Net?
Maintain button submit value when using link to submit a form
Looking how to send multiple values with an input type=submit form
How send a form with Javascript when input name is "submit"?
How do you submit a form with javascript with an < input type="button">
...All of the above seem to almost answer the question...but I'm totally mystified. I think something along the lines of "Net.Post(something)" is how it is done...but I am not sure.
I am currently using F#, and I have figured out how to parse links. I also figured out how to catch the various search bars and submission buttons with regexes.
I would like to use my code to search for something on a search engine by specifically:
First, obtaining the HTML
Second, Scraping the HTML for the various buttons, text bars, and links
Third, use some unknown method/device/tool/function to send a search thread to a text box...
Fourth, Simulate an actual mouse click on the submit "button" that appears on the website...
...
Then, upon reciept of the server's response, pull the HTML from the next site.
Here is my link code as it stands:
type Url(x:string)=
member this.Tostring = sprintf "%A" x
member this.Request = System.Net.WebRequest.Create(x)
member this.Response = this.Request.GetResponse()
member this.Stream = this.Response.GetResponseStream()
member this.Reader = new System.IO.StreamReader(this.Stream)
member this.Html = this.Reader.ReadToEnd()
let linkex = "href=\s*\"[^\"h]*(http://[^&\"]*)\""
let getLinks (txt:string) = [for m in Regex.Matches(txt,linkex)
-> m.Groups.Item(1).Value ]
let collectLinks (url:Url) = url.html
|> getLinks
... I know how to grab the search box strings and whatnot...the question is, when I go to, say, google.com and grab the search bar the same way I grab the links, update the value field with my search string, how do I then submit the updated search bar to google's server?
Secondly, how do I do it if I want to update it and then simulate a mouse click?
In other words, I want to interact with websites the way the user interacts with websites.
There are essentially two options - some web pages accept data using HTTP GET (which means that the data is sent as part of the URL) and other use HTTP POST (which means that the data is sent as the body of the request).
If you're using i.e. Google, then you can use HTTP GET and put the query string in the URL. For example, you can just download a web page with the following URL: https://www.google.com/search?q=hello. So, all you need to do is to generate the URL as follows:
let search = sprintf "http://www.google.com/search?q=%s"
If you want to send HTTP POST request from F#, then you need to create a request with body that contains the form values in an encoded form. This can be written as follows:
open System.Text
open System.IO
open System.Net
// URL of a simple page that takes two HTTP POST parameters. See the
// form that submits there: http://www.snee.com/xml/crud/posttest.html
let url = "http://www.snee.com/xml/crud/posttest.cgi"
// Create & configure HTTP web request
let req = HttpWebRequest.Create(url) :?> HttpWebRequest
req.ProtocolVersion <- HttpVersion.Version10
req.Method <- "POST"
// Encode body with POST data as array of bytes
let postBytes = Encoding.ASCII.GetBytes("fname=Tomas&lname=Petricek")
req.ContentType <- "application/x-www-form-urlencoded";
req.ContentLength <- int64 postBytes.Length
// Write data to the request
let reqStream = req.GetRequestStream()
reqStream.Write(postBytes, 0, postBytes.Length);
reqStream.Close()
// Obtain response and download the resulting page
// (The sample contains the first & last name from POST data)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let html = reader.ReadToEnd()
Aside, your use of type with member for every step is a bit weird. Members are re-executed each time you access them, so the code you wrote is pretty non-deterministic. You should use let binding instead.

C# HTTP programming

i want to build a piece of software that will process some html forms, the software will be a kind of bot that will process some forms on my website automatically.
Is there anyone who can give me some basic steps how to do this job...Any tutorials, samples, books or whatever can help me.
Can some of you post an working code with POST method ?
Check out How to: Send Data Using the WebRequest Class. It gives an example of how create a page that posts to another page using the HttpWebRequest class.
To fill out the form...
Find all of the INPUT or TEXTAREA elements that you want to fill out.
Build the data string that you are going to send back to the server. The string is formatted like "name1=value1&name2=value2" (just like in the querystring). Each value will need to be URL encoded.
If the form's "method" attribute is "GET", then take the URL in the "action" attribute, add a "?" and the data string, then make a "GET" web request to the URL.
If the form's "method" is "POST", then the data is submitted in a different area of the web request. Take a look at this page for the C# code.
To expand on David and JP's answers':
Assuming you're working with forms whose contents you're not familiar with, you can probably...
pull the page with the form via an HttpWebRequest.
load it into an XmlDocument
Use XPath to traverse/select the form elements.
Build your query string/post data based on the elements.
Send the data with HttWebRequest
If the form's structure is known in advance, you can really just start at #4.
(untested) example (my XPath is not great so the syntax is almost certainly not quite right):
HttpWebRequest request;
HttpWebResponse response;
XmlDocument xml = new XmlDocument();
string form_url = "http://...."; // you supply this
string form_submit_url;
XmlNodeList element_nodes;
XmlElement form_element;
StringBuilder query_string = new StringBuilder();
// #1
request = (HttpWebRequest)WebRequest.Create(form_url));
response = (HttpWebResponse)request.GetResponse();
// #2
xml.Load(response.GetResponseStream());
// #3a
form_element = xml.selectSingleNode("form[#name='formname']");
form_submit_url = form_element.GetAttribute("action");
// #3b
element_nodes = form_element.SelectNodes("input,select,textarea", nsmgr)
// #4
foreach (XmlNode input_element in element_nodes) {
if (query_string.length > 0) { query_string.Append("&"); }
// MyFormElementValue() is a function/value you need to provide/define.
query_string.Append(input_element.GetAttribute("name") + "=" + MyFormElementValue(input_element.GetAttribute("name"));
}
// #5
// This is a GET request, you can figure out POST as needed, and deduce the submission type via the <form> element's attribute.
request = (HttpWebRequest)WebRequest.Create(form_submit_url + "?" + query_string.ToString()));
References:
Link
http://www.developerfusion.com/forum/thread/26371/
http://msdn.microsoft.com/en-us/library/system.xml.xmlelement.getattribute.aspx
http://msdn.microsoft.com/en-us/library/system.xml.xmlelement.selectnodes.aspx
If you don't want to go the HttpWebRequest route, I would suggest WatiN. Makes it very easy to automate IE or Firefox and not worry about the internals of the HTTP requests.

Categories