C# HttpWebRequest GET HTTP HTTPS 请求

这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全部采用手工操作工作量大而且繁琐,因此周公决定利用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内容的方法(包括服务器使用压缩方式传输的数据),但限于篇幅和其它方面的原因,此处省略掉了。如有机会,在以后的文章中会继续讲述这方面的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/387552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql学习总结(4)——MySql基础知识、存储引擎与常用数据类型

2019独角兽企业重金招聘Python工程师标准>>> 1、基础知识 1.1、数据库概述 简单地说&#xff1a;数据库&#xff08;Database或DB&#xff09;是存储、管理数据的容器&#xff1b;严格地说&#xff1a;数据库是“按照某种数据结构对数据进行组织、存储和管理的容器”…

django权限二(多级菜单的设计以及展示)

多级权限菜单设计级标题栏 我们现在只有数据展示,要进入其他url还需要手动的输入路径,非常的麻烦,所以我们要设计 一个导航栏以及侧边多级菜单栏,这个展示是通过stark组件的设计的增删改查页面,而 每一个 页面我们都需要有导航栏和侧边的权限菜单栏,所以把这个公共的部分提起到…

腾讯手游如何提早揭露游戏外挂风险?

目前腾讯SR手游安全测试限期开放免费专家预约&#xff01;点击链接&#xff1a;手游安全测试立即预约&#xff01; 作者&#xff1a;sheldon&#xff0c;腾讯高级安全工程师 商业转载请联系腾讯WeTest获得授权&#xff0c;非商业转载请注明出处。 文中动图无法显示&#xff0c…

下面介绍一个开源的OCR引擎Tesseract2。值得庆幸的是虽然是开源的但是它的识别率较高,并不比其他引擎差劲。网上介绍Tessnet2也是当时时间排名第三的识别引擎,只是后来慢慢不维护了,目前是G

下面介绍一个开源的OCR引擎Tesseract2。值得庆幸的是虽然是开源的但是它的识别率较高&#xff0c;并不比其他引擎差劲。网上介绍Tessnet2也是当时时间排名第三的识别引擎&#xff0c;只是后来慢慢不维护了&#xff0c;目前是Google在维护&#xff0c;大家都知道Google 在搞电子…

分UV教程

第一步 首先&#xff0c;打开一个练习场景“空中预警机1.max”&#xff08;这事小弟平时的练习做的不好献丑了&#xff09;。&#xff08;图01&#xff09; 图01 第二步 这里我们拿机翼来举例子&#xff0c;隐藏除机翼意外的其他模型。&#xff08;图02&#xff09; 图02 第三步…

k8s系列--- dashboard认证及分级授权

http://blog.itpub.net/28916011/viewspace-2215214/ 因版本不一样&#xff0c;略有改动 Dashboard官方地址&#xff1a; https://github.com/kubernetes/dashboard dashbord是作为一个pod来运行&#xff0c;需要serviceaccount账号来登录。 先给dashboad创建一个专用的认证信息…

JAVA项目开发

16年java软件开发经验&#xff0c;全职项目开发&#xff0c;项目可签合同、开普票和专票。 主要承接项目&#xff1a; 1、网站开发项目 自主开发千帆CMS动态发布系统&#xff0c;基于java/springboot2/jpa/easyui开发&#xff0c;简单易用&#xff0c;后台与前端分离&#xff0…

unity3d 任务头上的血条

人物的名称与血条的绘制方法很简单&#xff0c;但是我们需要解决的问题是如何在3D世界中寻找合适的坐标。因为3D世界中的人物是会移动的&#xff0c;它是在3D世界中移动&#xff0c;并不是在2D平面中移动&#xff0c;但是我们需要将3D的人物坐标换算成2D平面中的坐标&#xff0…

unity3d 预制体

首先要说明一下什么是预制体&#xff1f; 在Unity3D里面我们叫它Prefab&#xff1b;我们也可以这样理解&#xff1a;当制作好了游戏组件&#xff08;场景中的任意一个gameobject &#xff09;,我们希望将它制作成一个组件模版&#xff0c;用于批量的套用工作&#xff0c;例如说…

Python小数据池,代码块

今日内容一些小的干货 一. id is 二. 代码块三. 小数据池四. 总结python小数据池&#xff0c;代码块的最详细、深入剖析 一. id is 二. 代码块三. 小数据池四. 总结一&#xff0c;id&#xff0c;is&#xff0c; 在Python中&#xff0c;id是什么&#xff1f;id是内存地址…

【Wax】使用Wax (framework方式,XCode 4.6)

前情提示&#xff1a;【Wax】使用Wax &#xff08;非framework方式&#xff0c;XCode 4.6&#xff09; 这次&#xff0c;将以framework的方式来使用Wax 那么&#xff0c;让我们开始吧&#xff01;&#xff01;&#xff01; 准备工作&#xff1a; 下载wax.framework&#xff1a;…

unity3d 简单动画

1&#xff0c;动画系统配置 创建游戏对象并添加Animation组件&#xff0c;然后将动画文件拖入组件。 进入动画文件的Debug属性面板 选中Legacy属性 选中游戏对象&#xff0c;打开Animation编辑窗口 添加动画变化属性 需改关键帧的属性值 配置完成后运行即可得到动画效果 2&…

3dmax导出到unity3d下分割动画

1、在3dmax 导出时候&#xff0c;要导出FBX文件&#xff0c;同时包含动画&#xff0c;骨骼&#xff0c;皮肤等内容 2、把FBX文件导入到Unity3d后会默认有一个超长的大动画&#xff0c;就是一个整体的动画&#xff0c;如图Take001&#xff0c;这个时候要分割哪部分是跑&#xf…

Unity3d之AssetBundle打包与读取

一、创建Assetbundle 在unity3d开发的游戏中&#xff0c;无论模型&#xff0c;音频&#xff0c;还是图片等&#xff0c;我们都做成Prefab&#xff0c;然后打包成Assetbundle&#xff0c;方便我们后面的使用&#xff0c;来达到资源的更新。 一个Assetbundle可以打包一个模型&…

unity3d 各个目录的意思

1.首先&#xff0c;你得理解Unity中各个目录的意思&#xff1f; 我这里说的是移动平台&#xff08;安卓举例&#xff09;&#xff0c;读&#xff0c;写。所谓读&#xff0c;就是你出大版本的包之后&#xff0c;这个只读的话&#xff0c;就一辈子就这些东西了&#xff0c;不会改…

asp.net core根据用户权限控制页面元素的显示

asp.net core根据用户权限控制页面元素的显示 Intro 在 web 应用中我们经常需要根据用户的不同允许用户访问不同的资源&#xff0c;显示不同的内容&#xff0c;之前做了一个 AccessControlHelper 的项目&#xff0c;就是解决这个问题的。 asp.net core 支持 TagHelper 和 基于 …

Java面向对象(二)

source:http://blog.java1234.com/index.html?typeId1 Java类的继承 1&#xff0c;继承定义以及基本使用 定义&#xff1a;子类能够继承父类的属性和方法&#xff1b; 注意点&#xff1a;Java中只支持单继承&#xff1b; 私有方法不能继承&#xff1b; 2&#xff0c;方法重写 …

游戏通讯方式

农药自从上线以来&#xff0c;依靠着强大的产品力以及腾讯的运营能力&#xff0c;在游戏市场上表现可谓是风生水起&#xff0c;根据第三方的调研数据显示&#xff0c;《王者荣耀》渗透率达到22.3%&#xff0c;用户规模达到2.01亿人&#xff0c;每日的日活跃用户&#xff08;DAU…

小小c#算法题 - 3 - 字符串语句反转

题目&#xff1a;反转语句。 如I love Beijing! 反转后输出 !Beijing love I 特点是指反转单词的顺序&#xff0c;其他字符&#xff08;这个可以自己指定&#xff09;不反转。且不能用内置函数&#xff0c;如Split和Substring。 分析&#xff1a;我们需要保证一个单词的字…

unity5.4.3p2里面的AssetBundle打包流程

unity5.4.3p2里面的AssetBundle打包流程&#xff0c;相比之前unity4.x的打包简单了许多&#xff0c;Unity4.X中打包的时候需要自己去管理依赖关系&#xff0c;各种BuildPipeline.PushAssetDependencies()和BuildPipeline.PopAssetDependencies()&#xff0c;一不小心手一抖&…