20
votes

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.

1
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
@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
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
Both PUT and POST are working after the changes suggested by @AI W. SO basically this question is closed. THanksAzho KG
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

1 Answers

12
votes

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