如何使用HttpWebRequest进行GET方法请求

29

我有以下代码,当方法为“POST”时可以正常工作,但更改为“GET”时无法工作:

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);

我使用“GET”方法时出现了“ProtocolViolationException”异常。
编辑:经过使用Reflector查看,似乎有一个明确的检查,“GET”方法如果设置为那样就会抛出异常。
编辑2:我已经更新了我的代码如下,但是当我调用EndGetResponse()时仍然会抛出异常。
if (request.Method == "GET")
{
    request.BeginGetResponse(this.ResponseCallback, state);
}
else
{
    request.BeginGetRequestStream(this.RequestCallback, state);
}

在我的函数ResponseCallback中,我有以下代码:
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

这段代码现在已经可以运行,我忘记删除Content-Type行导致最后抛出了异常。感谢tweakt的贡献和Jon的回答。

修复后的代码如下:

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);
}

仍然是ProtocolViolationException吗?您能否编写一个简短但完整的程序来演示问题?您是否查看了线路(例如使用Wireshark)以查看发生了什么? - Jon Skeet
这两种方法完全不同 - BeginGetResponse 用于发出网络请求,而 BeginGetRequestStream 用于将数据写入流中。 - BlueRaja - Danny Pflughoeft
4个回答

12

这在文档中有特别说明。基本上,GET请求不应包含主体内容,所以没有明智的理由调用BeginGetRequestStream


1
好的,那怎么使用HttpWebRequest来进行GET方法呢?我真的不想根据是GET/POST(使用WebClient进行GET)来有两个逻辑路径。 - Mark Ingram
1
只有在请求体存在时才获取请求流。如果您有请求体并且正在进行GET请求,则问题出在其他地方。 - Jon Skeet
没有请求体,但是我确实需要获取请求流,因为我从 REST API 中获取结果。 - Mark Ingram
不,这意味着你需要响应流。请求流是你发送的正文。使用GET时,您不发送正文。 - Jon Skeet
它是在Silverlight中,所以我没有那个奢侈品 :-/。 (我的函数选择是BeginGetRequestStream / EndGetRequestStream和BeginGetResponse / EndGetResponse)。 - Mark Ingram
显示剩余2条评论

5

一个GET请求发送Content-Type有意义吗?你尝试删除第三行了吗?


在处理Phone7时,这是一个相关的答案。在GET请求中设置contentType会导致协议违规异常在请求完成后出现。 - Sky Sanders

1
在GetRequestStream的文档中指定,如果方法是GET,它将抛出ProtocolViolationException。然而,我找不到任何HTTP规范中的内容表明这实际上是HTTP协议违规。请将其视为一种挑战。

1

BeginGetRequestStream用于获取一个专门用于向请求写入数据的流。这对GET请求不适用。

BeginGetRequestStream方法的文档明确说明,如果方法为GET或HEAD,则该方法将抛出ProtocolViolationException异常。

教训:阅读文档;-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接