我们知道, .Net类库里提供了HttpWebRequest等类,方便我们编程与Web服务器进行交互. 但是实际使用中我们经常会遇到以下需求,基础类里没有直接提供相应的功能(WebClient类包含这些功能,只是用起来稍微麻烦一点--谢谢网友东吴居士的提醒):

  • 对HttpWebResponse获取的HTML进行文字编码转换,使之不会出现乱码;
  • 自动在Session间保持Cookie,Referer等相关信息;
  • 模拟HTML表单提交;
  • 向服务器上传文件;
  • 对二进制的资源,直接获取返回的字节数组(byte[]),或者保存为文件

为了解决这些问题,我开发了HttpClient类.下面是使用的方法:

  • 获取编码转换后的字符串

    HttpClient client=new HttpClient(url);
    string html=client.GetString();

    GetString()函数内部会查找Http Headers, 以及HTML的Meta标签,试图找出获取的内容的编码信息.如果都找不到,它会使用client.DefaultEncoding, 这个属性默认为utf-8, 也可以手动设置.

  • 自动保持Cookie, Referer

    HttpClient client=new HttpClient(url1, null, true);
    string html1=client.GetString();
    client.Url=url2;
    string html2=client.GetString();

    这里HttpClient的第三个参数,keepContext设置为真时,HttpClient会自动记录每次交互时服务器对Cookies进行的操作,同时会以前一次请求的Url为Referer.在这个例子里,获取html2时,会把url1作为Referer, 同时会向服务器传递在获取html1时服务器设置的Cookies. 当然,你也可以在构造HttpClient时直接提供第一次请求要发出的Cookies与Referer:

    HttpClient client=new HttpClient(url, new WebContext(cookies, referer), true);

    或者,在使用过程中随时修改这些信息:

    client.Context.Cookies=cookies;
    client.Context.referer=referer;

  • 模拟HTML表单提交

    HttpClient client=new HttpClient(url);
    client.PostingData.Add(fieldName1, filedValue1);
    client.PostingData.Add(fieldName2, fieldValue2);
    string html=client.GetString();

    上面的代码相当于提交了一个有两个input的表单. 在PostingData非空,或者附加了要上传的文件时(请看下面的上传和文件), HttpClient会自动把HttpVerb改成POST, 并将相应的信息附加到Request上.

  • 向服务器上传文件

    HttpClient client=new HttpClient(url);
    client.AttachFile(fileName, fieldName);
    client.AttachFile(byteArray, fileName, fieldName);
    string html=client.GetString();

    这里面的fieldName相当于<input type="file" name="fieldName" />里的fieldName. fileName当然就是你想要上传的文件路径了. 你也可以直接提供一个byte[] 作为文件内容, 但即使如此,你也必须提供一个文件名,以满足HTTP规范的要求.

  • 不同的返回形式

    字符串: string html = client.GetString();
    流: Stream stream = client.GetStream();
    字节数组: byte[] data = client.GetBytes();
    保存到文件:  client.SaveAsFile(fileName);
    或者,你也可以直接操作HttpWebResponse: HttpWebResponse res = client.GetResponse();

    每调用一次上述任何一个方法,都会导致发出一个HTTP Request, 也就是说,你不能同时得到某个Response的两种返回形式.
    另外,调用后它们任意一个之后,你可以通过client.ResponseHeaders来获取服务器返回的HTTP头.

  • 下载资源的指定部分(用于断点续传,多线程下载)

    HttpClient client=new HttpClient(url);
    //发出HEAD请求,获取资源长度
    int length=client.HeadContentLength();

    //只获取后一半内容
    client.StartPoint=length/2;
    byte[] data=client.GetBytes();

    HeadContentLength()只会发出HTTP HEAD请求.根据HTTP协议, HEAD与GET的作用等同, 但是,只返回HTTP头,而不返回资源主体内容. 也就是说,用这个方法,你没法获取一个需要通过POST才能得到的资源的长度,如果你确实有这样的需求,建议你可以通过GetResponse(),然后从ResponseHeader里获取Content-Length.

计划中还有另外一些功能要加进来,比如断点续传, 多线程下载, 下载进度更新的事件机制等, 正在思考如何与现在的代码融合到一起,期待你的反馈.

你可以从这里下载目前版本的全部代码.

注意:使用时应该添加对System.Web.dll的引用,并在使用此类的代码前添加"using System.Web;",不然会无法通过编译(感谢Hyke的提醒).

[update:2007年8月11日]

    • 修复了一个与文件上传相关的bug;
    • 听从大家的意见,给公开方法和属性添加了XML注释;
    • 添加了断点续传的支持功能(还需要考虑一下怎么做能让使用更方便).
    • 修复了一个与Post相关的bug

HttpClient, 使用C#操作Web的更多相关文章

  1. C# HttpClient, 使用C#操作Web

    我们知道, .Net类库里提供了HttpWebRequest等类,方便我们编程与Web服务器进行交互. 但是实际使用中我们经常会遇到以下需求,基础类里没有直接提供相应的功能(WebClient类包含这 ...

  2. selenium怎么操作web页面常见的元素

    总结一下selenium怎么操作web页面常见的元素. 主要有: 上传 alter dialog prompt dialog confirm dialog select list radio box ...

  3. 使用HttpClient对ASP.NET Web API服务实现增删改查

    本篇体验使用HttpClient对ASP.NET Web API服务实现增删改查. 创建ASP.NET Web API项目 新建项目,选择"ASP.NET MVC 4 Web应用程序&quo ...

  4. 使用HttpClient消费ASP.NET Web API服务

    本篇体验使用HttpClient消费ASP.NET Web API服务,例子比较简单. 依次点击"文件","新建","项目". 选择&quo ...

  5. HttpClient与APS.NET Web API:请求内容的压缩与解压

    首先说明一下,这里的压缩与解压不是通常所说的http compression——那是响应内容在服务端压缩.在客户端解压,而这里是请求内容在客户端压缩.在服务端解压. 对于响应内容的压缩,一般Web服务 ...

  6. 通过HttpClient 调用ASP.NET Web API

    在前面两篇文章中我们介绍了ASP.NET Web API的基本知识和原理,并且通过简单的实例了解了它的基本(CRUD)操作.我们是通过JQuery和Ajax对Web API进行数据操作.这一篇我们来介 ...

  7. HttpClient读取ASP.NET Web API错误信息的简单方法

    在C#中,用HttpClient调用Web API并且通过Content.ReadAsStringAsync()读取响应内容时,如果出现500错误(InternalServerError),会得到一个 ...

  8. Web操作web.config

    1.引用System.Configuration.DLL 2.引用命名空间System.Configuration和System.Web.Configuration 3.上代码 // 使用指定的虚拟路 ...

  9. 选择、操作web元素-2

    11月3日 等待web元素的出现 例子:百度搜索松勤网,点击操作后不等待页面刷新,下面选择页面元素的时候,该元素还是未出现 sleep方案的弊病:固定的等待时间,导致测试用例执行时间很长 为什么cli ...

随机推荐

  1. iOS中倒计时

    方法一:使用NSTimer来实现(比较适用于发送短信验证码倒计时) 主要是利用NSTimer的scheduledTimerWithTimeInterval方法来每秒执行一次changeTime方法 / ...

  2. [LoadRunner]录制启动时报“The JVM could not be started……”错误解决方案

    在LR准备点击录制java over http协议时,程序报如下错误: 报错提示是设置的JVM值设置问题,导致不能启动. 解决方案一 点击F4快捷按钮,会弹出以下界面,在选中的位置选择对应的java路 ...

  3. Entity Framework中的Identity map和Unit of Work模式

    阅读目录: 一.什么是Identity map模式 二.关于Identity map模式的验证示例 三.Unit of Work 模式 四.总结和注意的问题 一,什么是Identity map模式 I ...

  4. ERP产品价格成本计算的几个方法(转)

          一般财务计算产品价格又很多方法,我这里做了几个供参考,实体属性主要是编号.数量.价格等,这里就不列出了. /// <summary> /// 先进先出算法 /// </s ...

  5. Ubuntu15.04装机配置脚本

    #!/bin/bash echo "vim" sudo apt-get install vim cp -r ./vim/.vim ~/ cp ./vim/.vimrc ~/ ech ...

  6. 计算机信息统计.vbs

    temp=0 set wshshell=wscript.createobject("wscript.shell") Set WshNetwork = WScript.Createo ...

  7. PHPDBG

    一.简介 PHPDBG的是一个轻量级.强大.易用的PHP调试平台.可以在PHP5.4和之上版本中使用.在php5.6和之上版本将内部集成. 二.安装 PHP源码下载 http://php.net/gi ...

  8. Java语言中的基本词汇

    1.标识符包.类.方法.参数和变量的名称.大小写字母.数字._和$符号的组合,不以数字开始,不能使关键字,不能包括分隔符和换行.(严格区分大小写,最大长度255个字符) 2.字面量  某种类型的值(具 ...

  9. noip2008普及组4题题解-rLq

    (啊啊啊终于补到了今天的作业了) 本题地址:http://www.luogu.org/problem/show?pid=1058 题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣 ...

  10. 【实践】jdbc批量插入数据

    参考文献:http://my.oschina.net/u/1452675/blog/203670 http://superjavason.iteye.com/blog/255423 /*测试批量写入数 ...