29

I have the following code which works just fine when the method is "POST", but changing to "GET" doesn't work:

HttpWebRequest request = null;
request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.Method = "POST"; // Doesn't work with "GET"

request.BeginGetRequestStream(this.RequestCallback, null);

I get a ProtocolViolationException exception with the "GET" method.

Edit: After having a look using Reflector, it seems there is an explicit check for the "GET" method, if it's set to that it throws the exception.

Edit2: I've updated my code to the following, but it still throws an exception when I call EndGetResponse()

if (request.Method == "GET")
{
    request.BeginGetResponse(this.ResponseCallback, state);
}
else
{
    request.BeginGetRequestStream(this.RequestCallback, state);
}

In my function, ResponseCallback, I have this:

HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

Which throws the exception as well.

Answer

The above code now works, I had forgotten to take out the Content-Type line which was causing the exception to be thrown at the end. +1 to tweakt & answer to Jon.

The working code is now below:

HttpWebRequest request = null;
request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "GET";// Supports POST too

if (request.Method == "GET")
{
    request.BeginGetResponse(this.ResponseCallback, state);
}
else
{
    request.BeginGetRequestStream(this.RequestCallback, state);
}
Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • Still a ProtocolViolationException? Can you produce a short but complete program which demonstrates the problem? Have you looked on the wire (e.g. with Wireshark) to see what's happening? – Jon Skeet Oct 31 '08 at 14:28
  • Those two methods are completely different - `BeginGetResponse` is for making the web request, while `BeginGetRequestStream` is for writing the data to the stream.. – BlueRaja - Danny Pflughoeft Apr 20 '14 at 06:52

4 Answers4

12

This is specified in the documentation. Basically GET requests aren't meant to contain bodies, so there's no sensible reason to call BeginGetRequestStream.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    OK, that's fine - how do I use the HttpWebRequest with the GET method? I really don't want to have 2 logic paths dependent on whether it's GET/POST (using WebClient for GET). – Mark Ingram Oct 31 '08 at 14:22
  • 1
    Only fetch the request stream if you've got a body. If you've got a body and you're making a GET request, your bug is elsewhere. – Jon Skeet Oct 31 '08 at 14:27
  • There's no body, but I do need to get the request stream, as I'm getting the result from a REST api. – Mark Ingram Oct 31 '08 at 14:33
  • Sorry, meant the response stream - I need to get the result from the server. – Mark Ingram Oct 31 '08 at 14:34
  • No, that means you need the *response* stream. The request stream is the body you send. With GET, you don't send a body. – Jon Skeet Oct 31 '08 at 14:34
  • Darn I hate collisions. Yes, you need the response stream. If you try to do it synchronously, do you still get the error? – Jon Skeet Oct 31 '08 at 14:35
  • It's in Silverlight so I don't have that luxury :-/. (My choice of functions are BeginGetRequestStream / EndGetRequestStream & BeginGetResponse / EndGetResponse). – Mark Ingram Oct 31 '08 at 14:37
5

Does it make sense for a GET request to send a Content-Type? Did you try removing the third line?

Mark Renouf
  • 30,697
  • 19
  • 94
  • 123
  • when dealing with phone7, in particular, this is a relevant answer. the act of setting contentType on a GET request will result in a protocol violation exception upon completion of the request. – Sky Sanders Mar 28 '12 at 13:01
1

BeginGetRequestStream is used to get a stream specifically for writing data to the request. This is not applicable to GET requests.

The documentation for the BeginGetRequestStream method states explicitly that the method will throw a ProtocolViolationException if the Method is GET or HEAD.

Morale: read the docs ;-)

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63
1

It is specified in the documentation for the GetRequestStream that it will throw a ProtocolViolationException if the method is GET. However, I cannot find anything in the HTTP spec to suggest that this is actually an HTTP protocol violation. Consider this a challenge.

MarkPflug
  • 28,292
  • 8
  • 46
  • 54