20

I'm having problems with sending POST request in C# and it seems I misunderstood some HTTP basics. So basically I'm implementing RESTfull service client, which work as follows:

  1. Make POST request with username/password and get token
  2. Use this token in header (Authorization:TOKEN) while making other GET/POST/PUT requests

I use WebRequest to make GET requests (with Authorization header) and it's working. But when I use following code to make PUT requests, service is giving "Authentication failed - not logged in" message back:

String url = String.Format("{0}/{1}", AN_SERVER, app);
WebRequest theRequest = WebRequest.Create(url);
theRequest.Method = "POST";

theRequest.ContentType = "text/x-json";
theRequest.ContentLength = json.Length;
Stream requestStream = theRequest.GetRequestStream();

requestStream.Write(Encoding.ASCII.GetBytes(json), 0, json.Length);
requestStream.Close();


theRequest.Headers.Add("Authorization", authToken);

HttpWebResponse response =  (HttpWebResponse)theRequest.GetResponse();

I must be making minor mistake (at least I hope so) while sending POST request. So what am I doing wrong?

Thanks.

Azho KG
  • 1,161
  • 1
  • 13
  • 25
  • 5
    have you tried moving the Headers.Add to before the requestStream? One other thing that looks odd is that there isn't a named parameter passed to the request something like requestStream.Write("json=" + json) – Al W Aug 02 '11 at 22:23
  • @AI W: Moving headers before requestStream solved the problem. Why the order is important here? Thank you very much. I spend a day trying to "learn" this, bit 30 minutes of Stackoverflow was more helpful. Can you please write it as an answer so that I can accept it. Thanks again. BTW, it's json object being put into request, not named parameter. – Azho KG Aug 02 '11 at 22:40
  • Does the server accepts PUT requests for non-authorized services? IIRC PUT (and DELETE) is not enabled by default on some versions of IIS, so it may be the case for other servers as well. – carlosfigueira Aug 03 '11 at 04:56
  • Both PUT and POST are working after the changes suggested by @AI W. SO basically this question is closed. THanks – Azho KG Aug 03 '11 at 20:41
  • 4
    FYI - `System.Net.HttpRequestHeader` enum has standard HTTP header field names, so you don't have to hard-code strings arbitrarily. `HttpRequestHeader.Authorization` could be used instead of "Authorization". Also `WebRequestMethods.Http.Post`. – nekno Aug 06 '11 at 04:39
  • What object type is the `json` variable that you reference in this code snippet? – rownage Sep 02 '14 at 14:19

1 Answers1

12

Moving Headers before the request steam works (as per AI W's comment), because the request stream is adding the body.

The way webrequest is implemented internally, you need to finish the header before writing body, and once its in stream format, its ready to send.

If you look at the implementation of webrequest in reflector or some such decompiling tool, you'll be able to see the logic.

Hope this helps

stevenrcfox
  • 1,547
  • 1
  • 14
  • 37
  • 3
    Seems like a pretty poor implementation, I'm not surprised that it caused confusion. – Waylon Flinn Oct 10 '11 at 15:34
  • Its a tad fussy, but its relatively simple to use once you get used to it. People do tend to bump into the limits of webrequest or webclient relatively quickly, and start to use httpwebrequest instead. – stevenrcfox Oct 10 '11 at 16:56