I know there are a lot of questions about sending HTTP POST requests with C#, but I'm looking for a method that uses WebClient rather than HttpWebRequest. Is this possible? It'd be nice because the WebClient class is so easy to use.
I know I can set the Headers property to have certain headers set, but I don't know if it's possible to actually do a POST from WebClient.
You can use WebClient.UploadData() which uses HTTP POST, i.e.:
using (WebClient wc = new WebClient())
{
byte[] result = wc.UploadData("http://stackoverflow.com", new byte[] { });
}
The payload data that you specify will be transmitted as the POST body of your request.
Alternatively there is WebClient.UploadValues() to upload a name-value collection also via HTTP POST.
You could use Upload method with HTTP 1.0 POST
string postData = Console.ReadLine();
using (System.Net.WebClient wc = new System.Net.WebClient())
{
wc.Headers.Add("Content-Type","application/x-www-form-urlencoded");
// Upload the input string using the HTTP 1.0 POST method.
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postData);
byte[] byteResult= wc.UploadData("http://targetwebiste","POST",byteArray);
// Decode and display the result.
Console.WriteLine("\nResult received was {0}",
Encoding.ASCII.GetString(byteResult));
}
Related
I am currently working on a local http server written in C#. At this point I am not yet processing post data, but only distinguish between get and post request. In both cases, of course, a 200 should be answered. While testing the server, I noticed that if I send an empty post request, it is answered by the server with a 200 and an html page just like a get request without any problems. However, if there are images attached to the post request, as in my example, the connection to the server fails immediately.
I handle a client connection as follows. I know it's not ideal to store the received bytes in a string, but for testing purposes I haven't seen any problems with it.
private void HandleClient(TcpClient client)
{
Byte[] bytes;
String requestData = "";
NetworkStream ns = client.GetStream();
if (client.ReceiveBufferSize > 0)
{
bytes = new byte[client.ReceiveBufferSize];
ns.Read(bytes, 0, client.ReceiveBufferSize);
requestData = Encoding.ASCII.GetString(bytes);
}
// Get Request out of message
Request request = Request.GetRequest(requestData);
// Create Response
Response response = Response.From(request);
response.Post(client.GetStream());
}
And here is the method I use to determine what type of request it is.
public static Request GetRequest(String request)
{
//return if request is null
if(String.IsNullOrEmpty(request))
{
return null;
}
//Split Request to get tokens - split by spaces
String[] tokens = request.Split(' ');
String type = tokens[0];
String url = tokens[1];
String host = tokens[4];
return new Request(type, url, host);
}
Surely it must be possible to read only the headers from a get as well as post request and then still give a 200 response. Is there a rule of behavior for an http server on how it should handle post-request data?
The answer to my question was quite simple in the end. The input stream of a request must be read completely before the server can respond to the request. In my case it was so, that I only read the header of the request to know if it is a Post or Get request, therefore the server could not respond to the request in case of an attached image, because the input stream was not read completely.
I am trying to send a POST request in C# with a parameter encoded to ISO-8859. I am using this code:
using (var wb = new WebClient())
{
var encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
var encodedText = System.Web.HttpUtility.UrlEncode("åæ ÆÆ øØ ø", encoding);
wb.Encoding = encoding;
wb.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var data = new NameValueCollection();
data["TXT"] = encodedText;
var response = wb.UploadValues(_url, "POST", data);
}
I have figured out that the correctly encoded string for "åæ ÆÆ øØ ø" is %E5%E6+%C6%C6++%F8%D8+%F8, and I can see when debugging that encodedText actually is this string. However when inspecting the raw request in fiddler, I can see that the string looks like this: TXT=%25e5%25e6%2B%25c6%25c6%2B%25f8%25d8%2B%25f8. I am guessing some kind of extra encoding is being done to the string after or during the call to UploadValues().
Thank you so much in advance.
I checked Google for this. According to another question here on SO at UTF32 for WebClient.UploadValues? (second answer), Webclient.UploadValues() indeed does encoding itself. However, it does ASCII encoding. Youll have to use another method to upload this, like HttpWebRequest.
This question already has answers here:
How to post data to specific URL using WebClient in C#
(9 answers)
Closed 9 years ago.
I need to submit data via POST request to a third party api, I have the url to submit to, but I am trying to avoid first sending the data to the client-side and then posting it again from there. Is there a way to POST information from codebehind directly?
Any ideas are appreciated.
From the server side you can post it to the url.
See the sample code from previous stackoverflow question - HTTP request with post
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["username"] = "myUser";
data["password"] = "myPassword";
var response = wb.UploadValues(url, "POST", data);
}
Use the WebRequest class to post.
http://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx
Alternatively you can also use HttpClient class:
http://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx
Hope this helps. Please post if you are facing issues.
Something like this?
string URI = "http://www.myurl.com/post.php";
string myParameters = "param1=value1¶m2=value2¶m3=value3";
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
}
How to post data to specific URL using WebClient in C#
You should to use WebRequest class:
var request = (HttpWebRequest)WebRequest.Create(requestedUrl);
request.Method = 'POST';
using (var resp = (HttpWebResponse)request.GetResponse()) {
// your logic...
}
Full info is here https://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx
I have been coding a application in c#, which data is send through get function
Its like this
Http://www.myweb.com/co.php?a=10&b=20
I am new to c# web programming, so i was wondering how can send the same data through post function. Because if i use $_POST in the php file it dont get the values, i researched a bit and found that POST function takes data in the body rather then in URL.
I just to convert the procedure from GET TO POST. Any help will be greatly appreciated.
You can use HttpWebRequest, setting the Method and ContentType properties appropriately:
var request = (HttpWebRequest)WebRequest.Create("http://www.myweb.com/co.php");
// your choice of encoding, I just picked ASCII here
var body = System.Text.Encoding.ASCII.GetBytes("a=10&b=20");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = body.Length;
using (var stream = request.GetRequestStream()) {
stream.Write(body, 0, body.Length);
}
If you're targeting .NET 4.5 I'd suggest using HttpClient if not then I'd go with WebClient:
WebClient webClient = new WebClient();
NameValueCollection values = new NameValueCollection();
values.Add("FirstName", "John");
values.Add("LastName", "Smith");
values.Add("Age", "46");
webClient.UploadValues("http://example.com/", values);
I'm currently writing some tests so that I may improve my skills with the Internet interaction through Windows Forms. One of those tests is to find a postal code which should be returned by Canada Post website.
My default URL setting is set to: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
The required form fields are: streetNumber, streetName, city, province
The contentType is "application/x-www-form-enclosed"
EDIT: Please consider the value "application/x-www-form-encoded" instead of point 3 value as the contentType. (Thanks EricLaw-MSFT!)
The result I get is not the result expected. I get the HTML source code of the page where I could manually enter the information to find the postal code, but not the HTML source code with the found postal code. Any idea of what I'm doing wrong?
Shall I consider going the XML way? Is it first of all possible to search on Canada Post anonymously?
Here's a code sample for better description:
public static string FindPostalCode(ICanadadianAddress address) {
var postData = string.Concat(string.Format("&streetNumber={0}", address.StreetNumber)
, string.Format("&streetName={0}", address.StreetName)
, string.Format("&city={0}", address.City)
, string.Format("&province={0}", address.Province));
var encoding = new ASCIIEncoding();
byte[] postDataBytes = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create(DefaultUrlSettings);
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Anonymous;
request.Container = new CookieContainer();
request.Timeout = 10000;
request.ContentType = contentType;
request.ContentLength = postDataBytes.LongLength;
request.Method = #"post";
var senderStream = new StreamWriter(request.GetRequestStream());
senderStream.Write(postDataBytes, 0, postDataBytes.Length);
senderStream.Close();
string htmlResponse = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
return processedResult(htmlResponse); // Processing the HTML source code parsing, etc.
}
I seem stuck in a bottle neck in my point of view. I find no way out to the desired result.
EDIT: There seems to have to parameters as for the ContentType of this site. Let me explain.
There's one with the "meta"-variables which stipulates the following:
meta http-equiv="Content-Type" content="application/xhtml+xml,
text/xml, text/html; charset=utf-8"
And another one later down the code that is read as:
form id="fpcByAdvancedSearch:fpcSearch" name="fpcByAdvancedSearch:fpcSearch" method="post" action="/cpotools/apps/fpc/personal/findByCity?execution=e1s1" enctype="application/x-www-form-urlencoded"
My question is the following: With which one do I have to stick?
Let me guess, the first ContentType is to be considered as the second is only for another request to a function or so when the data is posted?
EDIT: As per request, the closer to the solution I am is listed under this question:
WebRequest: How to find a postal code using a WebRequest against this ContentType=”application/xhtml+xml, text/xml, text/html; charset=utf-8”?
Thanks for any help! :-)
I'm trying to see a reason why you are not using the WebClient class:-
var fields = new NameValueCollection();
fields.Add("streetnumber", address.StreetNumber);
fields.Add("streetname", address.StreetName);
fields.Add("city", address.City);
fields.Add("province", address.Province);
var wc = new WebClient();
byte[] resultData = wc.UploadValues(url, fields);
string result = Encoding.Default.GetString(resultData);
You might want to check the encoding used by the server when sending the results, if it uses UTF-8 change the last line to:-
string result = Encoding.UTF8.GetString(resultData);
Some issues I spot in your orginal code:-
The first field is prefixed with &, that shouldn't be there.
You need call use Uri.EscapeDataString on each field value.
You are attempting to construct a memory stream around the result of GetRequestStream, I can't see what that would achieve even if MemoryStream had such a constructor but it doesn't anyway. Just write directly to the stream returned by GetRequestStream
If you have already done so get yourself a copy of fiddler so you can observe what occurs when a standard form requests the data sucessfully and what your code is doing.
Edit: If you have evidence that the lack of a cookie container is what causes WebClient not to work then you could try this approach:-
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
Now use my code above to but instead od instancing WebClient instance MyWebClient instead.
HTTPWebRequest will return the content of the URLrequested. If it is a HTML page, it will return HTML markup. If the page content is XML, then it will return XML markup.
It sounds like you need is a Webservice. I would see if that site has any webserivces available to process that type of request. If they do, then it will return XML, JSON markup in response to your query. Otherwise you are left to parsing the output of the request.