C#中WebRequest请求的一些心得
在C#开发中经常需要进行Web远程访问,方法很多,也使用了很久,但一直没有做一个总结。
C#中用来进行远程请求的方法有很多,如WebClient,WebRequest等,也各有特点。今天在这里主要介绍WebRequest。
先从相对入门的不需要证书验证,不需要登录的开始。
1 //Get 2 public string GetContent(string uri, Encoding coding) 3 { 4 //Get请求中请求参数等直接拼接在url中 5 WebRequest request = WebRequest.Create(uri); 6 7 //返回对Internet请求的响应 8 WebResponse resp = request.GetResponse(); 9 10 //从网络资源中返回数据流 11 Stream stream = resp.GetResponseStream(); 12 13 StreamReader sr = new StreamReader(stream, coding); 14 15 //将数据流转换文字符串 16 string result = sr.ReadToEnd(); 17 18 //关闭流数据 19 stream.Close(); 20 sr.Close(); 21 22 return result; 23 }
上面的方法是GET类型的请求。下面介绍POST请求。
1 //POST 2 public string GetContentPost(string uri, string data, Encoding coding) 3 { 4 WebRequest request = WebRequest.Create(uri); 5 request.ContentType = "application/x-www-form-urlencoded"; 6 request.Method = "POST"; 7 8 //将字符串数据转化为字节串,这也是POST请求与GET请求区别的地方 9 byte[] buffer = coding.GetBytes(data); 10 11 //用于将数据写入Internet资源 12 Stream stream = request.GetRequestStream(); 13 stream.Write(buffer, 0, buffer.Length); 14 request.ContentLength = buffer.Length; 15 16 WebResponse response = request.GetResponse(); 17 18 //从网络资源中返回数据流 19 stream = response.GetResponseStream(); 20 21 StreamReader sr = new StreamReader(stream, coding); 22 23 //将数据流转换文字符串 24 string result = sr.ReadToEnd(); 25 26 //关闭流数据 27 stream.Close(); 28 sr.Close(); 29 30 return result; 31 }
上面两个方法的特点就是简单易使用,用于获取HTML文档。缺点就是无法处理那些需要证书的页面。
下面我们介绍需要证书验证的页面如何请求。
1 //回调验证证书问题 2 public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 3 { 4 //直接返回true,接受指定证书进行身份验证 5 return true; 6 } 7 8 //Get 9 public string GetContent(string uri, Encoding coding) 10 { 11 12 //下面一行代码一定卸载请求开始前。 13 //使用回调的方法进行验证。 14 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); 15 16 //Get请求中请求参数等直接拼接在url中 17 WebRequest request = WebRequest.Create(uri); 18 19 //返回对Internet请求的响应 20 WebResponse resp = request.GetResponse(); 21 22 //从网络资源中返回数据流 23 Stream stream = resp.GetResponseStream(); 24 25 StreamReader sr = new StreamReader(stream, coding); 26 27 //将数据流转换文字符串 28 string result = sr.ReadToEnd(); 29 30 //关闭流数据 31 stream.Close(); 32 sr.Close(); 33 34 return result; 35 } 36 37 //POST 38 public string GetContentPost(string uri, string data, Encoding coding) 39 { 40 //下面一行代码一定卸载请求开始前。 41 //使用回调的方法进行验证。 42 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); 43 44 WebRequest request = WebRequest.Create(uri); 45 request.ContentType = "application/x-www-form-urlencoded"; 46 request.Method = "POST"; 47 48 //将字符串数据转化为字节串,这也是POST请求与GET请求区别的地方 49 byte[] buffer = coding.GetBytes(data); 50 51 //用于将数据写入Internet资源 52 Stream stream = request.GetRequestStream(); 53 stream.Write(buffer, 0, buffer.Length); 54 request.ContentLength = buffer.Length; 55 56 WebResponse response = request.GetResponse(); 57 58 //从网络资源中返回数据流 59 stream = response.GetResponseStream(); 60 61 StreamReader sr = new StreamReader(stream, coding); 62 63 //将数据流转换文字符串 64 string result = sr.ReadToEnd(); 65 66 //关闭流数据 67 stream.Close(); 68 sr.Close(); 69 70 return result; 71 }
我们以百度举例,看访问百度时如何获取百度服务器的证书相关信息。
只需在证书验证的回调函数中添加几行代码即可。
1 //回调验证证书问题 2 public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 3 { 4 Console.WriteLine("证书的有效日期:" + certificate.GetEffectiveDateString()); 5 Console.WriteLine("证书的到期日期:" + certificate.GetExpirationDateString()); 6 Console.WriteLine("证书格式名称:" + certificate.GetFormat()); 7 Console.WriteLine("证书办法机构名称:" + certificate.Issuer); 8 Console.WriteLine("密钥算法信息:" + certificate.GetKeyAlgorithm()); 9 Console.WriteLine("证书的公钥:" + certificate.GetPublicKeyString()); 10 Console.WriteLine("证书序列号:" + certificate.GetSerialNumberString()); 11 // 总是接受 12 return true; 13 }
使用如下GET方式访问百度。即可得到截图效果。
GetContent("https://www.baidu.com/", Encoding.UTF8);
Console.WriteLine(str);
然后通过浏览器导航栏的锁标识,即可直接查看百度的相关证书信息。
通过对比可以知道,获取到的证书完全正确。所以如果想对访问的网站有证书检测,也可以通过这种方式。避免出现请求被拦截等问题。