HTTPWebRequest returns Cannot send a content-body with this verb type
-
9. března 2012 13:10
Given this code:
public void test() { var request = (HttpWebRequest)WebRequest.Create("http://www.Google.com/"); request.Method = "GET"; var query = from response in request.GetResponseObserverable() from stream in request.GetRequestStreamObservable() select response; query.Subscribe( r => XTB.Dispatcher.Invoke(new Action<object>(trythis), r), ex => XTB.Dispatcher.Invoke(new Action<object>(trythis), ex)); } public void trythis(object stuff) { //Breaks here with "Cannot send a content-body with this verb type. //at System.Net.HttpWebRequest.CheckProtocol(Boolean onRequestStream) //at System.Net.HttpWebRequest.BeginGetRequestStream(AsyncCallback callback, Object state) //at System.Reactive.Linq.Observable.<>c__DisplayClass2`1.<FromAsyncPattern>b__0() } private void XBStart_Click(object sender, System.Windows.RoutedEventArgs e) { test(); } } public static class Ext { public static IObservable<Stream> GetRequestStreamObservable(this WebRequest request) { return Observable.FromAsyncPattern<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream)(); } public static IObservable<Unit> WriteObservable(this Stream stream, byte[] data) { return Observable.FromAsyncPattern<byte[], int, int>(stream.BeginWrite, stream.EndWrite)(data, 0, data.Length); } public static IObservable<WebResponse> GetResponseObserverable(this WebRequest request) { return Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)(); } }
I've listed where in the delegate what is happening and the stack trace. When I search MSDN to find the root cause of this problem it appears that the HTTPWEBREQUEST is a POST and NOT a GET or something similar. NOTE: I created the extension methods based on a post here by Dave Sexton (Thanks Dave). But I cannot understand the root cause of this issue?JP Cowboy Coders Unite!
Všechny reakce
-
9. března 2012 15:27
I placed this code in the extension method to validate the method type in the request being passed in, indeed it is a GET request. So either RX is hosing this up or the root cause is something else...
public static IObservable<Stream> GetRequestStreamObservable(this WebRequest request) { var thing = Observable.FromAsyncPattern<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream)(); return thing; }
JP Cowboy Coders Unite!
-
9. března 2012 15:32
Ok so this code works, which means it's looking more like a RX issue when getting the observable.
var request = (HttpWebRequest)WebRequest.Create("http://www.Google.com/"); request.Method = "GET"; HttpWebResponse oResponse = (HttpWebResponse)request.GetResponse(); Stream stream1 = oResponse.GetResponseStream(); StreamReader sr = new StreamReader(stream1);
JP Cowboy Coders Unite!
-
9. března 2012 17:02
Hi,
Assuming that the type of the exception is ProtocolViolationException, the problem is that you're calling GetRequestStream on the request object, not GetResponseStream on the response object. The request stream is for writing to the request body, which is not allowed in a GET request. This error is documented in the link above.
Notice that your last example is not the same as your first.
You may also be interested in Rxx, which offers these extensions and others related to asynchronous web requests.
- Dave
http://davesexton.com/blog
-
9. března 2012 18:45
Thanks Dave, I'll experiment with your advise AND download RXX and start looking into it. Question on RXX are you intending to support this for the next few years? It appears to be a winner, but sometimes I don't like other solutions because MSFT will come out with something new....
JP Cowboy Coders Unite!
-
9. března 2012 19:13
Hi,
I highly doubt that Microsoft is going to abandon Rx anytime soon, based solely on its progress thus far, having received "official" status and being included as part of the shipping Windows Phone SDK.
I personally have no intention of abandoning Rxx. Though you should be aware that it's an open source "contribution" product for Rx, not an official Microsoft product, so I can't make any guarantees. But like other open source projects, perhaps there will always be somebody available to maintain it if people find it useful, in the event that I or James can't do it.
- Dave
http://davesexton.com/blog
-
9. března 2012 20:11
Ok was able to get that corrected as you suggested Dave, I was indeed observing or attempting to observer the wrong thing. Question, how do I get the stream now being that there is no BeginAsync, EndAsync in WebResponse.GetResponseStream? I attemted to code up an OBSERVABLE as shown below but the delegate to get the stream isn't firing now...
public static IObservable<Stream> GetResponseStreamObservable(this WebResponse response) { var rs = Observable.Create((IObserver<Stream> o) => { var rs1 = response.GetResponseStream(); return rs1; }); return rs; }
JP Cowboy Coders Unite!
-
9. března 2012 20:21
Hi,
There's no need to force it to be asynchronous if the underlying API doesn't support it to begin with. Instead, just call GetResponseStream synchronously within your query. For example:
var query = from response in request.GetResponseObserverable() select new StreamReader(response.GetResponseStream());
- Dave
http://davesexton.com/blog
- Označen jako odpověď Mr. Javaman II 9. března 2012 23:08
-
9. března 2012 23:19
Ok very good, Thanks Dave...
For anyone else out there here it is, note that if you just got the string you can navigate to the string, but in this case I wanted to demo the Navigate to STREAM method in System.Controls.Webbrowser. Now if you do this, the browser behvior will not be the same (as actually navigating) and I'm not sure why, for one thing I don't think the javacript gets run, but apparrently neither do subsequent Image gets and all the other tidy things browsers do.... Would be greate to figure how to do those things...but that's a different topic on a different forum.
public void ObservableHTTPGetRequest() { var request = (HttpWebRequest)WebRequest.Create("http://www.google.com"); request.Method = "GET"; var query = from response in request.GetResponseObserverable() select response.GetResponseStream(); query.Subscribe( s => XTB.Dispatcher.Invoke(new Action<Stream>(TheDelegateToCall), s) ); } public void TheDelegateToCall(Stream stuff) { XWB.NavigateToStream(stuff); } } public static class Ext { public static IObservable<Unit> WriteObservable(this Stream stream, byte[] data) { return Observable.FromAsyncPattern<byte[], int, int>(stream.BeginWrite, stream.EndWrite)(data, 0, data.Length); } public static IObservable<WebResponse> GetResponseObserverable(this WebRequest request) { return Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)(); } public static IObservable<Stream> GetResponseStreamObservable(this WebResponse response) { var rs = Observable.Create((IObserver<Stream> o) => { var rs1 = response.GetResponseStream(); return rs1; }); return rs; } }
JP Cowboy Coders Unite!
- Označen jako odpověď Mr. Javaman II 9. března 2012 23:19