系列目录 【已更新最新开发文章,点击查看详细】
学习本篇之前,对 HttpWebRequest 与 HttpWebResponse 不太熟悉的同学,请先学习《C# HTTP系列》。
应用程序中使用HTTP协议和服务器交互主要是进行数据的上传与下载,最常见的方式是通过 GET 和 POST 两种方式来完成。本篇介绍 C# HttpWebRequest 如何使用这两种方式来实现。
示例场景:
1 <form id="form1" runat="server" action="UserManageHandler.ashx" method="post" enctype="application/x-www-form-urlencoded">
2 <div>
3 名称: <input type="text" name="uname" class="uname" /><br />
4 邮件: <input type="text" name="email" class="email" /><br />
5 <input type="submit" name="submit" value="提交" />
6 </div>
7 </form>
1 using System;
2 using System.Web;
3
4 namespace SparkSoft.Platform.UI.WebForm.Test
5 {
6 public class UserManageHandler : IHttpHandler
7 {
8
9 public void ProcessRequest(HttpContext context)
10 {
11 context.Response.ContentType = "text/plain";
12
13 string uname = context.Request["uname"];
14 string email = context.Request["email"];
15
16 context.Response.Write("提交结果如下:" + Environment.NewLine +
17 "名称:" + uname + Environment.NewLine +
18 "邮箱:" + email);
19 }
20
21 public bool IsReusable
22 {
23 get { return false; }
24 }
25 }
26 }
01 HttpWebRequest 提交数据方式1 GET方式
GET 方式通过在网络地址附加参数来完成数据的提交,
比如在地址 http://localhost:5000/Test/UserManageHandler.ashx?uname=zhangsan 中,前面部分 http://localhost:5000/Test/UserManageHandler.ashx 表示数据提交的网址,后面部分 uname=zhangsan 表示附加的参数,其中uname 表示一个键(key), zhangsan 表示这个键对应的值(value)。程序代码如下:
1 /// <summary>
2 /// 普通 GET 方式请求
3 /// </summary>
4 public void Request01_ByGet()
5 {
6 HttpWebRequest httpWebRequest = WebRequest.Create("http://localhost:5000/Test/UserManageHandler.ashx?uname=zhangsan") as HttpWebRequest;
7 httpWebRequest.Method = "GET";
8
9 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; // 获取响应
10 if (httpWebResponse != null)
11 {
12 using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
13 {
14 string content = sr.ReadToEnd();
15 }
16
17 httpWebResponse.Close();
18 }
19 }
02 HttpWebRequest 提交数据方式2 POST方式
POST 方式通过在页面内容中填写参数的方法来完成数据的提交,
参数的格式和 GET 方式一样,是类似于 uname=zhangsan&email=123456@qq.com 这样的结构。程序代码如下:
1 /// <summary>
2 /// 普通 POST 方式请求
3 /// </summary>
4 public void Request02_ByPost()
5 {
6 string param = "uname=zhangsan&email=123456@qq.com"; //参数
7 byte[] paramBytes = Encoding.ASCII.GetBytes(param); //参数转化为 ASCII 码
8
9 HttpWebRequest httpWebRequest = WebRequest.Create("http://localhost:5000/Test/UserManageHandler.ashx") as HttpWebRequest;
10 httpWebRequest.Method = "POST";
11 httpWebRequest.ContentType = "application/x-www-form-urlencoded";
12 httpWebRequest.ContentLength = paramBytes.Length;
13
14 using (Stream reqStream = httpWebRequest.GetRequestStream())
15 {
16 reqStream.Write(paramBytes, 0, paramBytes.Length);
17 }
18
19 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; // 获取响应
20 if (httpWebResponse != null)
21 {
22 using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
23 {
24 string content = sr.ReadToEnd();
25 }
26
27 httpWebResponse.Close();
28 }
29 }
如果提交的请求参数中包含中文,那么需要对其进行编码,让目标网站能够识别。
03 HttpWebRequest 提交数据方式3 GET方式提交中文数据
GET 方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有 gb2312 和 utf-8 两种。下面以 gb2312 方式编码来说明,程序代码如下:
1 /// <summary>
2 /// 使用 GET 方式提交中文数据
3 /// </summary>
4 public void Request03_ByGet()
5 {
6 /*GET 方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有 gb2312 和 utf8 两种。
7 * 由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。
8 * 常见的网站中, www.baidu.com (百度)的编码方式是 gb2312, www.google.com (谷歌)的编码方式是 utf8。
9 */
10 Encoding myEncoding = Encoding.GetEncoding("gb2312"); //确定用哪种中文编码方式
11 string address = "http://www.baidu.com/s?" + HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding); //拼接数据提交的网址和经过中文编码后的中文参数
12
13 HttpWebRequest httpWebRequest = WebRequest.Create(address) as HttpWebRequest;
14 httpWebRequest.Method = "GET";
15
16 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; // 获取响应
17 if (httpWebResponse != null)
18 {
19 using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
20 {
21 string content = sr.ReadToEnd();
22 }
23
24 httpWebResponse.Close();
25 }
26 }
在上面的程序代码中,我们以 GET 方式访问了网址 http://www.baidu.com/s ,传递了参数“参数一=值一”,由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。常见的网站中, www.baidu.com (百度)的编码方式是 gb2312, www.google.com (谷歌)的编码方式是 utf-8。
04 HttpWebRequest 提交数据方式4 POST方式提交中文数据
POST 方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。下面以 gb2312 方式编码来说明,程序代码如下:
/// <summary>
/// 使用 POST 方式提交中文数据
/// </summary>
public void Request04_ByPost()
{
/* POST 方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。*/
Encoding myEncoding = Encoding.GetEncoding("gb2312"); //确定用哪种中文编码方式
string param = HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding) + "&"
+ HttpUtility.UrlEncode("参数二", myEncoding) + "=" + HttpUtility.UrlEncode("值二", myEncoding);
byte[] paramBytes = Encoding.ASCII.GetBytes(param); //参数转化为 ASCII 码
HttpWebRequest httpWebRequest = WebRequest.Create("https://www.baidu.com/") as HttpWebRequest;
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
httpWebRequest.ContentLength = paramBytes.Length;
using (Stream reqStream = httpWebRequest.GetRequestStream())
{
reqStream.Write(paramBytes, 0, paramBytes.Length);
}
HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; // 获取响应
if (httpWebResponse != null)
{
using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
{
string content = sr.ReadToEnd();
}
httpWebResponse.Close();
}
}
以上列出了客户端程序使用HTTP协议与服务器交互的情况,常用的是 GET 和 POST 方式。现在流行的 WebService 也是通过 HTTP 协议来交互的,使用的是 POST 方法。与以上稍有所不同的是, WebService 提交的数据内容和接收到的数据内容都是使用了 XML 方式编码。所以, HttpWebRequest 也可以使用在调用 WebService 的场景下。
HttpWebRequest 请求通用方法
(不包含body数据)POST、GET请求
1 /// <summary>
2 /// HTTP-GET方法,(不包含body数据)。
3 /// 发送 HTTP 请求并返回来自 Internet 资源的响应(HTML代码)
4 /// </summary>
5 /// <param name="url">请求目标URL</param>
6 /// <returns>HTTP-GET的响应结果</returns>
7 public HttpResult Get(string url)
8 {
9 return Request(url, WebRequestMethods.Http.Get);
10 }
1 /// <summary>
2 /// HTTP-POST方法,(不包含body数据)。
3 /// 发送 HTTP 请求并返回来自 Internet 资源的响应(HTML代码)
4 /// </summary>
5 /// <param name="url">请求目标URL</param>
6 /// <returns>HTTP-POST的响应结果</returns>
7 public HttpResult Post(string url)
8 {
9 return Request(url, WebRequestMethods.Http.Post);
10 }
(包含文本的body数据)请求
1 /// <summary>
2 /// HTTP请求(包含JSON文本的body数据)
3 /// </summary>
4 /// <param name="url">请求目标URL</param>
5 /// <param name="data">主体数据(JSON文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如:gb2312或者utf-8</param>
6 /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
7 /// <returns></returns>
8 public HttpResult UploadJson(string url, string data, string method = WebRequestMethods.Http.Post)
9 {
10 return Request(url, data, method, HttpContentType.APPLICATION_JSON);
11 }
1 /// <summary>
2 /// HTTP请求(包含普通文本的body数据)
3 /// </summary>
4 /// <param name="url">请求目标URL</param>
5 /// <param name="data">主体数据(普通文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如:gb2312或者utf-8</param>
6 /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
7 /// <returns></returns>
8 public HttpResult UploadText(string url, string data, string method = WebRequestMethods.Http.Post)
9 {
10 return Request(url, data, method, HttpContentType.TEXT_PLAIN);
11 }
上面的4个方法调用了公用的业务方法,分别如下:
1 /// <summary>
2 /// HTTP请求,(不包含body数据)。
3 /// 发送 HTTP 请求并返回来自 Internet 资源的响应(HTML代码)
4 /// </summary>
5 /// <param name="url">请求目标URL</param>
6 /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
7 /// <returns>HTTP的响应结果</returns>
8 private HttpResult Request(string url, string method)
9 {
10 HttpResult httpResult = new HttpResult();
11 HttpWebRequest httpWebRequest = null;
12 try
13 {
14 httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
15 httpWebRequest.Method = method;
16 httpWebRequest.UserAgent = _userAgent;
17 httpWebRequest.AllowAutoRedirect = _allowAutoRedirect;
18 httpWebRequest.ServicePoint.Expect100Continue = false;
19
20 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
21 if (httpWebResponse != null)
22 {
23 GetResponse(ref httpResult, httpWebResponse);
24 httpWebResponse.Close();
25 }
26 }
27 catch (WebException webException)
28 {
29 GetWebExceptionResponse(ref httpResult, webException);
30 }
31 catch (Exception ex)
32 {
33 GetExceptionResponse(ref httpResult, ex, method, string.Empty);
34 }
35 finally
36 {
37 if (httpWebRequest != null)
38 {
39 httpWebRequest.Abort();
40 }
41 }
42
43 return httpResult;
44 }
1 /// <summary>
2 /// HTTP请求(包含文本的body数据)
3 /// </summary>
4 /// <param name="url">请求目标URL</param>
5 /// <param name="data">主体数据(普通文本或者JSON文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如:gb2312或者utf-8</param>
6 /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
7 /// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取</param>
8 /// <returns></returns>
9 private HttpResult Request(string url, string data, string method, string contentType)
10 {
11 HttpResult httpResult = new HttpResult();
12 HttpWebRequest httpWebRequest = null;
13
14 try
15 {
16 httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
17 httpWebRequest.Method = method;
18 httpWebRequest.Headers = HeaderCollection;
19 httpWebRequest.CookieContainer = CookieContainer;
20 httpWebRequest.ContentType = contentType;// 此属性的值存储在WebHeaderCollection中。如果设置了WebHeaderCollection,则属性值将丢失。所以放置在Headers 属性之后设置
21 httpWebRequest.UserAgent = _userAgent;
22 httpWebRequest.AllowAutoRedirect = _allowAutoRedirect;
23 httpWebRequest.ServicePoint.Expect100Continue = false;
24
25 if (data != null)
26 {
27 httpWebRequest.AllowWriteStreamBuffering = true;
28 using (Stream requestStream = httpWebRequest.GetRequestStream())
29 {
30 requestStream.Write(EncodingType.GetBytes(data), 0, data.Length);//将请求参数写入请求流中
31 requestStream.Flush();
32 }
33 }
34
35 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
36 if (httpWebResponse != null)
37 {
38 GetResponse(ref httpResult, httpWebResponse);
39 httpWebResponse.Close();
40 }
41 }
42 catch (WebException webException)
43 {
44 GetWebExceptionResponse(ref httpResult, webException);
45 }
46 catch (Exception ex)
47 {
48 GetExceptionResponse(ref httpResult, ex, method, contentType);
49 }
50 finally
51 {
52 if (httpWebRequest != null)
53 {
54 httpWebRequest.Abort();
55 }
56 }
57
58 return httpResult;
59 }
其中2个Request方法中用到了其他的封装类,比如:HttpResult
1 /// <summary>
2 /// HTTP请求(GET,POST等)的响应返回消息
3 /// </summary>
4 public sealed class HttpResult
5 {
6 #region 字段
7
8 /// <summary>
9 /// HTTP 响应成功,即状态码为200
10 /// </summary>
11 public const string STATUS_SUCCESS = "success";
12
13 /// <summary>
14 /// HTTP 响应失败
15 /// </summary>
16 public const string STATUS_FAIL = "fail";
17
18 #endregion
19
20 #region 属性
21
22 /// <summary>
23 /// 获取或设置请求的响应状态,success 或者 fail。建议使用常量:HttpResult.STATUS_SUCCESS 与 HttpResult.STATUS_FAIL
24 /// </summary>
25 public string Status { get; set; }
26
27 /// <summary>
28 /// 获取或设置请求的响应状态描述
29 /// </summary>
30 public string StatusDescription { get; set; }
31
32 /// <summary>
33 /// 状态码。与 HttpWebResponse.StatusCode 完全相同
34 /// </summary>
35 public int? StatusCode { get; set; }
36
37 /// <summary>
38 /// 响应消息或错误文本
39 /// </summary>
40 public string Text { get; set; }
41
42 /// <summary>
43 /// 响应消息或错误(二进制格式)
44 /// </summary>
45 public byte[] Data { get; set; }
46
47 /// <summary>
48 /// 参考代码(用户自定义)。
49 /// 当 Status 等于 success 时,该值为 null;
50 /// 当 Status 等于 fail 时,该值为程序给出的用户自定义编码。
51 /// </summary>
52 public int? RefCode { get; set; }
53
54 /// <summary>
55 /// 附加信息(用户自定义内容,如Exception内容或者自定义提示信息)。
56 /// 当 Status 等于 success 时,该值为为空
57 /// 当 Status 等于 fail 时,该值为程序给出的用户自定义内容,如Exception内容或者自定义提示信息。
58 /// </summary>
59 public string RefText { get; set; }
60
61 /// <summary>
62 /// 获取或设置Http的请求响应。
63 /// </summary>
64 public HttpWebResponse HttpWebResponse { get; set; }
65
66 ///// <summary>
67 ///// 参考信息(从返回消息 WebResponse 的头部获取)
68 ///// </summary>
69 //public Dictionary<string, string> RefInfo { get; set; }
70
71 #endregion
72
73 #region 构造函数
74 /// <summary>
75 /// 初始化(所有成员默认值,需要后续赋值)
76 /// </summary>
77 public HttpResult()
78 {
79 Status = string.Empty;
80 StatusDescription = string.Empty;
81 StatusCode = null;
82 Text = string.Empty;
83 Data = null;
84
85 RefCode = null;
86 RefText = string.Empty;
87 //RefInfo = null;
88
89 HttpWebResponse = null;
90 }
91
92 #endregion
93
94 #region 方法
95
96 /// <summary>
97 /// 对象复制
98 /// </summary>
99 /// <param name="httpResultSource">要复制其内容的来源</param>
100 public void Shadow(HttpResult httpResultSource)
101 {
102 this.Status = httpResultSource.Status;
103 this.StatusDescription = string.Empty;
104 this.StatusCode = httpResultSource.StatusCode;
105 this.Text = httpResultSource.Text;
106 this.Data = httpResultSource.Data;
107
108 this.RefCode = httpResultSource.RefCode;
109 this.RefText += httpResultSource.RefText;
110 //this.RefInfo = httpResultSource.RefInfo;
111
112 this.HttpWebResponse = httpResultSource.HttpWebResponse;
113 }
114
115 /// <summary>
116 /// 转换为易读或便于打印的字符串格式
117 /// </summary>
118 /// <returns>便于打印和阅读的字符串</returns>
119 public override string ToString()
120 {
121 StringBuilder sb = new StringBuilder();
122
123 sb.AppendFormat("Status:{0}", Status);
124 sb.AppendFormat("StatusCode:{0}", StatusCode);
125 sb.AppendFormat("StatusDescription:{0}", StatusDescription);
126 sb.AppendLine();
127
128 if (!string.IsNullOrEmpty(Text))
129 {
130 sb.AppendLine("text:");
131 sb.AppendLine(Text);
132 }
133
134 if (Data != null)
135 {
136 sb.AppendLine("data:");
137 int n = 1024;
138 if (Data.Length <= n)
139 {
140 sb.AppendLine(Encoding.UTF8.GetString(Data));
141 }
142 else
143 {
144 sb.AppendLine(Encoding.UTF8.GetString(Data, 0, n));
145 sb.AppendFormat("<--- TOO-LARGE-TO-DISPLAY --- TOTAL {0} BYTES --->", Data.Length);
146 sb.AppendLine();
147 }
148 }
149
150 sb.AppendLine();
151
152 sb.AppendFormat("ref-code:{0}", RefCode);
153 sb.AppendLine();
154
155 if (!string.IsNullOrEmpty(RefText))
156 {
157 sb.AppendLine("ref-text:");
158 sb.AppendLine(RefText);
159 }
160
161 sb.AppendLine();
162
163 return sb.ToString();
164 }
165
166 #endregion
167 }
系列目录 【已更新最新开发文章,点击查看详细】
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有