在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求

简介:

这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全部采用手工操作工作量大而且繁琐,因此周公决定利用C#来实现。在很多地方都需要验证用户身份才可以进行下一步操作,这就免不了POST请求来登录,在实际过程中发现有些网站登录是HTTPS形式的,在解决过程中遇到了一些小问题,现在跟大家分享。
 通用辅助类
下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中发送GET/HTTP/HTTPS请求,因为有的时候需要获取认证信息(如Cookie),所以返回的是HttpWebResponse对象,有了返回的HttpWebResponse实例,可以获取登录过程中返回的会话信息,也可以获取响应流。
代码如下:
 

     
     
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Net.Security;  
  6. using System.Security.Cryptography.X509Certificates;  
  7. using System.DirectoryServices.Protocols;  
  8. using System.ServiceModel.Security;  
  9. using System.Net;  
  10. using System.IO;  
  11. using System.IO.Compression;  
  12. using System.Text.RegularExpressions;  
  13. /*    
  14. * 作者:周公(zhoufoxcn)    
  15. * 日期:2011-05-08    
  16. * 原文出处:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com    
  17. * 版权说明:本文可以在保留原文出处的情况下使用于非商业用途,周公对此不作任何担保或承诺。    
  18. * */ 
  19. namespace BaiduCang  
  20. {  
  21.    ///   
  22.    /// 有关HTTP请求的辅助类  
  23.    ///   
  24.    public class HttpWebResponseUtility  
  25.    {  
  26.        private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";  
  27.        ///   
  28.        /// 创建GET方式的HTTP请求  
  29.        ///   
  30.        /// 请求的URL  
  31.        /// 请求的超时时间  
  32.        /// 请求的客户端浏览器信息,可以为空  
  33.        /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空  
  34.        ///   
  35.        public static HttpWebResponse CreateGetHttpResponse(string url,int? timeout, string userAgent,CookieCollection cookies)  
  36.        {  
  37.            if (string.IsNullOrEmpty(url))  
  38.            {  
  39.                throw new ArgumentNullException("url");  
  40.            }  
  41.            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;  
  42.            request.Method = "GET";  
  43.            request.UserAgent = DefaultUserAgent;  
  44.            if (!string.IsNullOrEmpty(userAgent))  
  45.            {  
  46.                request.UserAgent = userAgent;  
  47.            }  
  48.            if (timeout.HasValue)  
  49.            {  
  50.                request.Timeout = timeout.Value;  
  51.            }  
  52.            if (cookies != null)  
  53.            {  
  54.                request.CookieContainer = new CookieContainer();  
  55.                request.CookieContainer.Add(cookies);  
  56.            }  
  57.            return request.GetResponse() as HttpWebResponse;  
  58.        }  
  59.        ///   
  60.        /// 创建POST方式的HTTP请求  
  61.        ///   
  62.        /// 请求的URL  
  63.        /// 随同请求POST的参数名称及参数值字典  
  64.        /// 请求的超时时间  
  65.        /// 请求的客户端浏览器信息,可以为空  
  66.        /// 发送HTTP请求时所用的编码  
  67.        /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空  
  68.        ///   
  69.        public static HttpWebResponse CreatePostHttpResponse(string url,IDictionary<string,string> parameters,int? timeout, string userAgent,Encoding requestEncoding,CookieCollection cookies)  
  70.        {  
  71.            if (string.IsNullOrEmpty(url))  
  72.            {  
  73.                throw new ArgumentNullException("url");  
  74.            }  
  75.            if(requestEncoding==null)  
  76.            {  
  77.                throw new ArgumentNullException("requestEncoding");  
  78.            }  
  79.            HttpWebRequest request=null;  
  80.            //如果是发送HTTPS请求  
  81.            if(url.StartsWith("https",StringComparison.OrdinalIgnoreCase))  
  82.            {  
  83.                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);  
  84.                request = WebRequest.Create(url) as HttpWebRequest;  
  85.                request.ProtocolVersion=HttpVersion.Version10;  
  86.            }  
  87.            else 
  88.            {  
  89.                request = WebRequest.Create(url) as HttpWebRequest;  
  90.            }  
  91.            request.Method = "POST";  
  92.            request.ContentType = "application/x-www-form-urlencoded";  
  93.              
  94.            if (!string.IsNullOrEmpty(userAgent))  
  95.            {  
  96.                request.UserAgent = userAgent;  
  97.            }  
  98.            else 
  99.            {  
  100.                request.UserAgent = DefaultUserAgent;  
  101.            }  
  102.  
  103.            if (timeout.HasValue)  
  104.            {  
  105.                request.Timeout = timeout.Value;  
  106.            }  
  107.            if (cookies != null)  
  108.            {  
  109.                request.CookieContainer = new CookieContainer();  
  110.                request.CookieContainer.Add(cookies);  
  111.            }  
  112.            //如果需要POST数据  
  113.            if(!(parameters==null||parameters.Count==0))  
  114.            {  
  115.                StringBuilder buffer = new StringBuilder();  
  116.                int i = 0;  
  117.                foreach (string key in parameters.Keys)  
  118.                {  
  119.                    if (i > 0)  
  120.                    {  
  121.                        buffer.AppendFormat("&{0}={1}", key, parameters[key]);  
  122.                    }  
  123.                    else 
  124.                    {  
  125.                        buffer.AppendFormat("{0}={1}", key, parameters[key]);  
  126.                    }  
  127.                    i++;  
  128.                }  
  129.                byte[] data = requestEncoding.GetBytes(buffer.ToString());  
  130.                using (Stream stream = request.GetRequestStream())  
  131.                {  
  132.                    stream.Write(data, 0, data.Length);  
  133.                }  
  134.            }  
  135.            return request.GetResponse() as HttpWebResponse;  
  136.        }  
  137.  
  138.        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)  
  139.        {  
  140.            return true; //总是接受  
  141.        }  
  142.    }  
  143. }

从上面的代码中可以看出POST数据到HTTP和HTTPS站点不同,POST数据到HTTPS站点的时候需要设置ServicePointManager类的ServerCertificateValidationCallback属性,并且在POST到https://passport.baidu.com/?login时还需要将HttpWebResquest实例的ProtocolVersion属性设置为HttpVersion.Version10(这个未验证是否所有的HTTPS站点都需要设置),否则在调用GetResponse()方法时会抛出“基础连接已经关闭: 连接被意外关闭。”的异常。
 
 用法举例
这个类用起来也很简单:
(1)POST数据到HTTPS站点,用它来登录百度:
 

     
     
  1. string loginUrl = "https://passport.baidu.com/?login";  
  2. string userName = "userName";  
  3. string password = "password";  
  4. string tagUrl = "http://cang.baidu.com/"+userName+"/tags";  
  5. Encoding encoding = Encoding.GetEncoding("gb2312");  
  6.  
  7. IDictionary<string, string> parameters = new Dictionary<string, string>();  
  8. parameters.Add("tpl", "fa");  
  9. parameters.Add("tpl_reg", "fa");  
  10. parameters.Add("u", tagUrl);  
  11. parameters.Add("psp_tt", "0");  
  12. parameters.Add("username", userName);  
  13. parameters.Add("password", password);  
  14. parameters.Add("mem_pass", "1");  
  15. HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, encoding, null);  
  16. string cookieString = response.Headers["Set-Cookie"];

(2)发送GET请求到HTTP站点
在cookieString中包含了服务器端返回的会话信息数据,从中提取了之后可以设置Cookie下次登录时带上这个Cookie就可以以认证用户的信息,假设我们已经登录成功并且获取了Cookie,那么发送GET请求的代码如下:
 

     
     
  1. string userName = "userName";  
  2. string tagUrl = "http://cang.baidu.com/"+userName+"/tags";  
  3. CookieCollection cookies = new CookieCollection();//如何从response.Headers["Set-Cookie"];中获取并设置CookieCollection的代码略  
  4. response = HttpWebResponseUtility.CreateGetHttpResponse(tagUrl, null, null, cookies);  

(3)发送POST请求到HTTP站点
以登录51CTO为例:
 

     
     
  1. string loginUrl = "http://home.51cto.com/index.php?s=/Index/doLogin";  
  2. string userName = "userName";  
  3. string password = "password";  
  4.  
  5. IDictionary<string, string> parameters = new Dictionary<string, string>();  
  6. parameters.Add("email", userName);  
  7. parameters.Add("passwd", password);  
  8.  
  9. HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, Encoding.UTF8, null);  


 
 总结
在本文只是讲解了在C#中发送请求到HTTP和HTTPS的用法,分GET/POST两种方式,为减少一些繁琐和机械的编码,周公将其封装为一个类,发送数据之后返回HttpWebResponse对象实例,利用这个实例我们可以获取服务器端返回的Cookie以便用认证用户的身份继续发送请求,或者读取服务器端响应的内容,不过在读取响应内容时要注意响应格式和编码,本来在这个类中还有读取HTML和WML内容的方法(包括服务器使用压缩方式传输的数据),但限于篇幅和其它方面的原因,此处省略掉了。如有机会,在以后的文章中会继续讲述这方面的内容。














本文转自周金桥51CTO博客,原文链接:http://blog.51cto.com/zhoufoxcn/561934 ,如需转载请自行联系原作者

相关文章
|
2月前
|
Web App开发 Linux 应用服务中间件
【DrissionPage】Linux上如何将https改为http
通过上述步骤,可以在Linux上将DrissionPage从HTTPS改为HTTP。关键在于修改DrissionPage配置、代码中的HTTPS设置、URL以及Web服务器配置,确保所有部分都正确使用HTTP协议。通过合理配置和测试,能够确保系统在HTTP环境下稳定运行。
53 1
|
2月前
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
70 5
|
2月前
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
77 4
|
7月前
|
安全 网络协议 网络安全
IP代理的三大协议:HTTP、HTTPS与SOCKS5的区别
**HTTP代理**适用于基本网页浏览,简单但不安全;**HTTPS代理**提供加密,适合保护隐私;**SOCKS5代理**灵活强大,支持TCP/UDP及认证,适用于绕过限制。选择代理协议应考虑安全、效率及匿名需求。
|
3月前
|
存储 JSON API
HTTP 请求与响应处理:C#中的实践
【10月更文挑战第4天】在现代Web开发中,HTTP协议至关重要,无论构建Web应用还是API开发,都需要熟练掌握HTTP请求与响应处理。本文从C#角度出发,介绍HTTP基础知识,包括请求与响应结构,并通过`HttpClient`库演示如何发送GET请求及处理响应,同时分析常见错误并提供解决方案,助你更高效地完成HTTP相关任务。
142 2
|
4月前
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
221 7
|
4月前
|
安全 网络安全 数据安全/隐私保护
HTTP与HTTPS协议区别及应用场景
在互联网高速发展的今天,HTTP与HTTPS作为数据传输的基石,作用至关重要。HTTP允许客户端与服务器间传输超文本文档,但其数据传输过程未加密,存在安全隐患;HTTPS则在此基础上加入了SSL/TLS协议,实现了数据加密传输,增强了安全性,广泛应用于电子商务、网上银行、政府网站及社交媒体平台等涉及敏感信息传输的领域,有效保护了用户隐私和数据安全。随着网络安全意识提升,HTTPS正逐渐成为主流。
|
3月前
|
安全 应用服务中间件 网络安全
修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
|
3月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
746 0
|
6月前
|
JSON 网络协议 安全
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识
【7月更文挑战第16天】本文介绍了HTTP和HTTPS协议的基本概念与作用,强调了理解HTTP协议对使用抓包工具Fiddler的重要性。HTTP是用于Web浏览器与服务器间信息传输的协议,不加密,易被截取,不适合传输敏感信息。HTTPS是HTTP的安全版,通过SSL/TLS提供加密和服务器身份验证,确保数据安全。HTTP请求包括请求行、请求头、空行和可选的请求主体,响应则有响应行、响应头、空行和响应主体。HTTP协议无状态,而HTTPS解决了安全性问题,但也带来了额外的计算开销。Fiddler作为一个强大的抓包工具,可以帮助开发者和测试人员分析HTTP/HTTPS通信,理解请求和响应的结构。
94 4
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识