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

简介: C# HttpWebRequest GET HTTP HTTPS 请求  作者:周公(zhoufoxcn)    原文:http://blog.csdn.net/zhoufoxcn 这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全部采用手工操作工作量大而且繁琐,因此周公决定利用C#来实现。

C# HttpWebRequest GET HTTP HTTPS 请求 
作者:周公(zhoufoxcn)   
原文:http://blog.csdn.net/zhoufoxcn

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

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Net.Security;  
using System.Security.Cryptography.X509Certificates;  
using System.DirectoryServices.Protocols;  
using System.ServiceModel.Security;  
using System.Net;  
using System.IO;  
using System.IO.Compression;  
using System.Text.RegularExpressions;  

namespace BaiduCang  
{  
   /// <summary>  
   /// 有关HTTP请求的辅助类  
   /// </summary>  
   public class HttpWebResponseUtility  
   {  
       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)";  
       /// <summary>  
       /// 创建GET方式的HTTP请求  
       /// </summary>  
       /// <param name="url">请求的URL</param>  
       /// <param name="timeout">请求的超时时间</param>  
       /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>  
       /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param>  
       /// <returns></returns>  
       public static HttpWebResponse CreateGetHttpResponse(string url,int? timeout, string userAgent,CookieCollection cookies)  
       {  
           if (string.IsNullOrEmpty(url))  
           {  
               throw new ArgumentNullException("url");  
           }  
           HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;  
           request.Method = "GET";  
           request.UserAgent = DefaultUserAgent;  
           if (!string.IsNullOrEmpty(userAgent))  
           {  
               request.UserAgent = userAgent;  
           }  
           if (timeout.HasValue)  
           {  
               request.Timeout = timeout.Value;  
           }  
           if (cookies != null)  
           {  
               request.CookieContainer = new CookieContainer();  
               request.CookieContainer.Add(cookies);  
           }  
           return request.GetResponse() as HttpWebResponse;  
       }  
       /// <summary>  
       /// 创建POST方式的HTTP请求  
       /// </summary>  
       /// <param name="url">请求的URL</param>  
       /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
       /// <param name="timeout">请求的超时时间</param>  
       /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>  
       /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
       /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param>  
       /// <returns></returns>  
       public static HttpWebResponse CreatePostHttpResponse(string url,IDictionary<string,string> parameters,int? timeout, string userAgent,Encoding requestEncoding,CookieCollection cookies)  
       {  
           if (string.IsNullOrEmpty(url))  
           {  
               throw new ArgumentNullException("url");  
           }  
           if(requestEncoding==null)  
           {  
               throw new ArgumentNullException("requestEncoding");  
           }  
           HttpWebRequest request=null;  
           //如果是发送HTTPS请求  
           if(url.StartsWith("https",StringComparison.OrdinalIgnoreCase))  
           {  
               ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);  
               request = WebRequest.Create(url) as HttpWebRequest;  
               request.ProtocolVersion=HttpVersion.Version10;  
           }  
           else 
           {  
               request = WebRequest.Create(url) as HttpWebRequest;  
           }  
           request.Method = "POST";  
           request.ContentType = "application/x-www-form-urlencoded";  
             
           if (!string.IsNullOrEmpty(userAgent))  
           {  
               request.UserAgent = userAgent;  
           }  
           else 
           {  
               request.UserAgent = DefaultUserAgent;  
           }  

           if (timeout.HasValue)  
           {  
               request.Timeout = timeout.Value;  
           }  
           if (cookies != null)  
           {  
               request.CookieContainer = new CookieContainer();  
               request.CookieContainer.Add(cookies);  
           }  
           //如果需要POST数据  
           if(!(parameters==null||parameters.Count==0))  
           {  
               StringBuilder buffer = new StringBuilder();  
               int i = 0;  
               foreach (string key in parameters.Keys)  
               {  
                   if (i > 0)  
                   {  
                       buffer.AppendFormat("&{0}={1}", key, parameters[key]);  
                   }  
                   else 
                   {  
                       buffer.AppendFormat("{0}={1}", key, parameters[key]);  
                   }  
                   i++;  
               }  
               byte[] data = requestEncoding.GetBytes(buffer.ToString());  
               using (Stream stream = request.GetRequestStream())  
               {  
                   stream.Write(data, 0, data.Length);  
               }  
           }  
           return request.GetResponse() as HttpWebResponse;  
       }  

       private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)  
       {  
           return true; //总是接受  
       }  
   }  
} 

 

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

用法举例
这个类用起来也很简单:
(1)POST数据到HTTPS站点,用它来登录百度:

string loginUrl = "https://passport.baidu.com/?login";  
string userName = "userName";  
string password = "password";  
string tagUrl = "http://cang.baidu.com/"+userName+"/tags";  
Encoding encoding = Encoding.GetEncoding("gb2312");  

IDictionary<string, string> parameters = new Dictionary<string, string>();  
parameters.Add("tpl", "fa");  
parameters.Add("tpl_reg", "fa");  
parameters.Add("u", tagUrl);  
parameters.Add("psp_tt", "0");  
parameters.Add("username", userName);  
parameters.Add("password", password);  
parameters.Add("mem_pass", "1");  
HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, encoding, null);  
string cookieString = response.Headers["Set-Cookie"]; 

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

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

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

string loginUrl = "http://home.51cto.com/index.php?s=/Index/doLogin";  
string userName = "userName";  
string password = "password";  

IDictionary<string, string> parameters = new Dictionary<string, string>();  
parameters.Add("email", userName);  
parameters.Add("passwd", password);  

HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, Encoding.UTF8, null);  

 

在这里说句题外话,CSDN的登录处理是由http://passport.csdn.net/ajax/accounthandler.ashx这个Handler来处理的。

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

 

目录
相关文章
|
JSON 监控 API
掌握使用 requests 库发送各种 HTTP 请求和处理 API 响应
本课程全面讲解了使用 Python 的 requests 库进行 API 请求与响应处理,内容涵盖环境搭建、GET 与 POST 请求、参数传递、错误处理、请求头设置及实战项目开发。通过实例教学,学员可掌握基础到高级技巧,并完成天气查询应用等实际项目,适合初学者快速上手网络编程与 API 调用。
1251 130
|
JavaScript 前端开发 API
Node.js中发起HTTP请求的五种方式
以上五种方式,尽管只是冰山一角,但已经足以让编写Node.js HTTP请求的你,在连接世界的舞台上演奏出华丽的乐章。从原生的 `http`到现代的 `fetch`,每种方式都有独特的风格和表现力,让你的代码随着项目的节奏自由地舞动。
1101 65
|
Android开发 Kotlin
HTTP协议中请求方式GET 与 POST 什么区别 ?
GET和POST的主要区别在于参数传递方式、安全性和应用场景。GET通过URL传递参数,长度受限且安全性较低,适合获取数据;而POST通过请求体传递参数,安全性更高,适合提交数据。
985 2
|
Go 定位技术
Golang中设置HTTP请求代理的策略
在实际应用中,可能还需要处理代理服务器的连接稳定性、响应时间、以及错误处理等。因此,建议在使用代理时增加适当的错误重试机制,以确保网络请求的健壮性。此外,由于网络编程涉及的细节较多,彻底测试以确认代理配置符合预期的行为也是十分重要的。
502 8
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
772 26
|
JSON API 数据安全/隐私保护
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
1490 30
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
1294 20
|
JSON JavaScript API
Python模拟HTTP请求实现APP自动签到
Python模拟HTTP请求实现APP自动签到

热门文章

最新文章