来分享_share 阅读(2) 评论(0)

  在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);

    

    然后通过浏览器导航栏的锁标识,即可直接查看百度的相关证书信息。

    

    

    通过对比可以知道,获取到的证书完全正确。所以如果想对访问的网站有证书检测,也可以通过这种方式。避免出现请求被拦截等问题。