EJay
EJay

Reputation: 1159

ProtocolViolationException is thrown on GetRequestStream() with a post method

I have created a basic RESTful service in .NET that allows me to make basic Get and Post calls to a Uri that is specified by the calling method. In my post method, I am attempting to call GetRequestStream with my HttpWebRequest, however I get a ProtocolViolationException with the message "Cannot send a content-body with this verb-type."

I know that this can be caused by having the HttpWebRequest method set to Get, however I have debugged and made sure that the method is Post when the GetRequestStream call is made. I can't figure out why this is being thrown. Can anyone help me out? The code is below

public HttpWebResponse Get(bool followRedirect = true)
    {
        _webRequest.Method = WebRequestMethods.Http.Get;
        _webRequest.AllowAutoRedirect = followRedirect;
        _webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        var webResponse = _webRequest.GetResponse() as HttpWebResponse;

        _webRequest.CookieContainer.Add(webResponse.Cookies);
        return webResponse;
    }



    public HttpWebResponse Post(string contentType, Dictionary<String,String> parameters, bool followRedirect = true)
    {
        _webRequest.Method = WebRequestMethods.Http.Post;
        _webRequest.AllowAutoRedirect = followRedirect;

        var postData = "";
        foreach (var parameter in parameters)
        {
            postData += HttpUtility.UrlEncode(parameter.Key) + "=" +
                        HttpUtility.UrlEncode((parameter.Value)) + "&";
        }
        postData = postData.Remove(postData.Length - 1, 0);

        var data = Encoding.UTF8.GetBytes(postData);
        _webRequest.ContentType = contentType;

        var requestStream = _webRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        var webResponse = _webRequest.GetResponse() as HttpWebResponse;
        return webResponse;
    }

Edit

I discovered that the problem was being caused by calling _webRequest.GetResponse() and then later, I use that same _webRequest to call GetRequestStream(). Is this kind of behavior expected? That is, can a WebRequest only make one of those calls before it needs to be reinitialized/reset?

I made a fix by basically making a new WebRequest in Post and copying values from _webRequest to it, but I would like to know if that is necessary or if a more robust solution is possible.

Upvotes: 1

Views: 1379

Answers (2)

Kadir L&#252;zumlar
Kadir L&#252;zumlar

Reputation: 169

Do not send content-type on header if you do not have specific type or content.

For example getting flickr basic request/json response

var baseUrl = string.Format("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={0}&format=json&nojsoncallback=1", flickrApiKey);
HttpWebRequest httpRequest = HttpWebRequest.Create(baseUrl) as HttpWebRequest;
httpRequest.BeginGetResponse(GetResponseStream, httpRequest);

async void GetResponseStream(IAsyncResult callbackResult)
{
    try
    {
      HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
      HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
      string responseString = string.Empty;
      Stream streamResponse = response.GetResponseStream();
      StreamReader reader = new StreamReader(streamResponse);
      responseString = reader.ReadToEnd();
    }
    catch (ProtocolViolationException ex)
    {
      MessageDialog show = new MessageDialog("no internet connection available");
    }
    catch (Exception e)
    {
      await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.Run    Async(CoreDispatcherPriority.Normal, async () =>
    {
      MessageDialog show = new MessageDialog("something went wrong");
      await show.ShowAsync();
      });
    }
  }

Upvotes: 0

EJay
EJay

Reputation: 1159

Okay so I realized that the issue was coming from calling _webRequest.GetResponse() and then later calling .GetRequestStream() with the same WebRequest. Not exactly sure why this is, but that's what was causing the problem. I worked around the problem by creating a new WebRequest and copying the relevant attributes over to the new Request.

Upvotes: 1

Related Questions