Reputation: 1159
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 belowpublic 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;
}
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
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
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