WebClient与HttpWebRequest/HttpWebResponse的区别

137

我认为,大部分可以使用HttpWebRequest/Response实现的功能,同样也可以使用WebClient类来实现。我在某个地方读到过,WebClient是对WebRequest/Response的高级封装。

目前为止,我还没有看到任何可以使用HttpWebRequest/Response完成而不能使用WebClient完成的事情,也没有发现HttpWebRequest/Response提供更细粒度控制的情况。

那么,在什么情况下应该使用WebClient,在什么情况下应该使用HttpWebRequest/Response呢?(显然,HttpWebRequest/Response是HTTP特定的。)

如果HttpWebRequest/ResponseWebClient更低级,那么我可以通过HttpWebRequest/Response做什么,而使用WebClient无法做到呢?

8个回答

91

使用 HttpWebRequest 可以更好地控制请求。你可以设置 cookie、头信息、协议等等... 在响应中,你也可以获取到 cookie 和头信息。


14
Thomas仍然不确定... WebClient具有Headers属性,您可以像这样检索cookie:String cookie = webClient.ResponseHeaders("Set-Cookie") 并设置它:webClient.Headers.Add("Cookie", "CommunityServer-UserCookie…"); (翻译注:此段文字在讨论使用WebClient获取和设置cookie的问题) - Dan
15
使用HttpWebRequest可以定义超时时间,但在WebClient中则不可能实现。 - ripper234
15
@ripper234,实际上这是可能的:你只需要继承WebClient并重写GetWebRequest以自定义HttpWebRequest。 - Thomas Levesque
16
如果你正在继承WebClient并覆盖WebRequest,那么使用WebClient似乎是毫无意义的。 - Hagai L
6
@HagaiL,我不同意...你不必手动创建整个请求,你可以使用base.GetWebRequest来创建请求,然后只需自定义你想要的部分即可。 - Thomas Levesque
显示剩余2条评论

57

HttpWebRequest暴露了更多的功能,允许您进行细粒度的协议控制,例如:您是否想使用Keep-Alive,要使用哪个连接池,是否缓冲写入等。

WebClient并没有暴露所有这些功能(尽管您可以从WebClient继承子类并访问底层请求对象)。

WebClient在那些只想执行操作(例如:POST / GET / 表单上传)而不想创建和管理HttpWebRequestRequestStreamHttpWebResponse和响应流的情况下非常有用。


13
还有一件事我忘了提。WebClient是一个组件对象,而HttpWebRequest不是。这是什么意思呢?如果你使用VisualStudio构建GUI应用程序,你可以将WebClient组件拖放到你的窗体中并使用它来向HTTP/FTP等服务器发出请求。 - feroze

14

从 Tim Heuer 的博客上 - http://timheuer.com/blog/archive/2008/03/14/calling-web-services-with-silverlight-2.aspx

在 Silverlight 中,您应该使用 WebClient 或 HttpWebRequest。 它们有什么区别? 这是 timheuer 的版本。WebClient 提供了一个更简单的实现,可以轻松地进行 GET 请求并获取响应流。HttpWebRequest 适用于当您需要对请求进行更精细的控制、需要发送标头或其他自定义内容时。


7
WebClient也允许使用POST方法,可以使用UploadString、UploadData和UploadFile方法。 - Thomas Levesque
@ThomasLevesque 今天有更新的类吗?我看到这个讨论有点,嗯...过时了... - Konrad Viltersten
@KonradViltersten,我认为WebClient类并没有太多变化。对于新应用程序,我建议您改用HttpClient,它同样易于使用且更加灵活。 - Thomas Levesque
1
@ThomasLevesque 对的,那就是我想到的那个。我记得类名中有“http”的区别,被“Http...”这部分误导了。现在我又回到了正确的轨道上。谢谢! - Konrad Viltersten

13

WebClient 类在用户界面线程上运行,因此在从互联网下载数据时,用户界面不会响应。另一方面,HttpWebRequest 类不会阻塞用户界面线程,因此您的应用程序具有响应性。 因此,在需要从互联网下载大量数据或数据源访问速度较慢的应用程序中,应使用 HttpWebRequest 类;在所有其他情况下,应使用 WebClient 类。


1
在 WP7 上情况恰恰相反。HttpWebRequest 在 Mango 中会跨线程调用回 UI 线程,这让我很苦恼。Grrr - Cameron MacFarland
6
WebClient也支持异步方法。 - CyberMonk

6
另一个WebClient的缺点是,当你使用它来获取响应文本时,它会忽略HTTP ContentType中的charset值。你需要通过Encoding属性显式地设置编码。

这是一个很好的观点;而且不仅仅是设置“编码”的问题 - 在请求之后你无法知道编码,因此WebClient API使得你很难能够正确地下载未知编码的字符串。 - Eamon Nerbonne

5

在.NET 4.5中,“HtttpWebRequest”已被弃用。现在,该类仅为内部使用。


2
确实。请使用WebRequest - silkfire
2
这个类并不过时,只有构造函数过时了。而且这个类并不是内部的,它仍然是公共的。 - user247702

5

还有一件事,HttpWebRequest 允许压缩,但 Net.WebClient 类不支持 HTTP 压缩。


3
就像其他WebClient隐藏一些细节的例子一样,这个问题可以通过子类化WebClient并重写GetWebRequest方法来解决。在这种情况下,你只需微调底层HttpWebRequest.AutomaticDecompressiong属性即可(请参考https://dev59.com/DnA85IYBdhLWcg3wCe9Z#4914874)。 - patridge

2

举例来说:使用WebClient在一个请求/响应周期内发布数据并获取处理后的数据似乎是不可能的,但是您可以使用HtttpWebRequest实现此目的。


2
只需使用WebClient.UploadString或WebClient.UploadData执行POST并获取响应字符串或字节数组即可。 - samjudson
2
澄清一下,UploadString 方法的返回值是字符串,而 UploadData 方法的返回值是字节数组。 - Norman H

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