用泛型減少重復代碼,使代碼更合理、更優雅,代碼更合理
有這樣一個場景,需要對接接口,以獲取取得數據。
例如獲取訂單列表
接口請求參數(json格式):

![]()
1 {
2 //公共頭部
3 "head":{
4 "method":"getOrders", //接口方法
5 "sign":"xxxx" //簽名
6 },
7 //私有主體
8 "body":{
9 "userId":"1", //用戶ID
10 "numPerPage":10, //頁大小
11 "pageIdx":1 //頁碼
12 }
13 }
View Code
接口響應結果(json格式):

![]()
1 {
2 "head":{
3 "code":1, //狀態碼
4 "errMsg":"成功" //消息
5 },
6 "body":{
7 "pageCount":value,
8 "pageIdx":value,
9 "orders":[
10 {
11 "orderNo":value,
12 "orderPrice":value,
13 "orderTime":value,
14 }
15 ]
16 "status":value,
17 "orderStatus":value
18 省略...
19 }
20 }
View Code
通過觀察請求參數和響應結果,會發現有部分字段是公共的,並且與接口交互的方法,大部分都是相同的,這裡也可以提取封裝,將不穩定容易出錯的代碼集中到一個地方;而如果對每個接口方法都進行一遍對接,重復的代碼會不少,也很容易出錯(對copy代碼,吃過相當多的虧),所以對重復代碼進行適當的封裝,減少不必要的冗余,讓代碼結構更簡單明了。
首先是提取公共的請求實體容器BaseWhere<T>:

![]()
1 /// <summary>
2 /// 公共頭部
3 /// <para>
4 /// 用於與接口通訊,發送請求數據的容器
5 /// 數據訪問層使用
6 /// </para>
7 /// </summary>
8 /// <typeparam name="T"></typeparam>
9 public class BaseWhere<T> where T : new()
10 {
11 private headBaseWhere _head = new headBaseWhere();
12
13 /// <summary>
14 /// 公共頭部
15 /// </summary>
16 public headBaseWhere head { get; set; }
17
18 private T _body = new T();
19
20 /// <summary>
21 /// 私有主體
22 /// </summary>
23 public T body { get; set; }
24 }
25
26 public class headBaseWhere
27 {
28 /// <summary>
29 /// 接口方法
30 /// </summary>
31 public String method { get; set; }
32
33 /// <summary>
34 /// 簽名
35 /// </summary>
36 public String sign { get; set; }
37 }
View Code
接下來是提取公共的響應實體容器BaseResult<T>:

![]()
1 /// <summary>
2 /// 返回報文報文頭參數
3 /// <para>
4 /// 用於與接口通訊,接收返回數據的容器
5 /// 數據訪問層使用
6 /// </para>
7 /// </summary>
8 /// <typeparam name="T"></typeparam>
9 public class BaseResult<T> where T : new()
10 {
11 private headBaseResult _head = new headBaseResult();
12 /// <summary>
13 /// 公共頭部
14 /// </summary>
15 public headBaseResult head { get; set; }
16
17 private T _body = new T();
18 /// <summary>
19 /// 私有主體
20 /// </summary>
21 public T body { get; set; }
22 }
23
24 public class headBaseResult
25 {
26 /// <summary>
27 /// 狀態碼
28 /// </summary>
29 public String code { get; set; }
30
31 /// <summary>
32 /// 消息
33 /// </summary>
34 public String msg { get; set; }
35 }
View Code
然後定義訂單列表的請求實體OrdersPara和響應實體OrdersResult:

![]()
1 /// <summary>
2 /// 訂單列表(請求實體)
3 /// </summary>
4 public class OrdersPara
5 {
6 public string userId { get; set; }
7
8 public int numPerPage { get; set; }
9
10 public int pageIdx { get; set; }
11 }
12
13 /// <summary>
14 /// 訂單列表(響應實體)
15 /// </summary>
16 public class OrdersResult
17 {
18 private IList<Order> _orders = new List<Order>();
19
20 public int pageCount { get; set; }
21 public int pageIdx { get; set; }
22 public IList<Order> orders { get { return _orders; } set { _orders = value; } }
23 }
24
25 public class Order
26 {
27 private IList<OrderDetail> _detail = new List<OrderDetail>();
28
29 public string orderNo { get; set; }
30 public decimal orderPrice { get; set; }
31 public string orderTime { get; set; }
32 public int status { get; set; }
33 public int orderStatus { get; set; }
34 public int activityID { get; set; }
35 public string mobileNo { get; set; }
36 }
View Code
公共的請求方法WebAPIHelper<T>.POST(obj):

![]()
1 public static class WebAPIHelper<T> where T : new()
2 {
3 public static BaseResult<T> Post(Object postData)
4 {
5 StringBuilder strResult = new StringBuilder();
6
7 //創建HttpWebRequest請求
8 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Settings.APIURL);
9 request.Method = "POST";
10 request.ContentType = "application/x-www-form-urlencoded";
11 //根據接口的要求序列化請求參數
12 String strParams = JsonConvert.SerializeObject(postData);
13 UTF8Encoding encoding = new UTF8Encoding();
14 request.ContentLength = encoding.GetByteCount(strParams);
15 request.Credentials = CredentialCache.DefaultCredentials;
16
17 try
18 {
19 //創建字節流
20 using (Stream reqStream = request.GetRequestStream())
21 {
22 reqStream.Write(encoding.GetBytes(strParams), 0, encoding.GetByteCount(strParams));
23 }
24 //獲取回傳信息
25 using (WebResponse response = request.GetResponse())
26 {
27 Stream streamResult = response.GetResponseStream();
28 using (StreamReader reader = new StreamReader(streamResult))
29 {
30 strResult.Append(reader.ReadToEnd());
31 }
32 }
33 }
34 catch (Exception ex)
35 {
36 }
37
38 BaseResult<T> result = new BaseResult<T>();
39 try
40 {
41 result = JsonConvert.DeserializeObject<BaseResult<T>>(strResult.ToString());
42 }
43 catch (Exception ex)
44 {
45 }
46
47 if (result == null)
48 {
49 result = new BaseResult<T>();
50 }
51
52 if(result.body == null)
53 {
54 result.body = new T();
55 }
56
57 return result;
58 }
59 }
View Code
調用示例:
public QueryOrdersResult Get(QueryOrdersPara para)
{
BaseWhere<OrdersPara> where = new BaseWhere<OrdersPara>();
where.head.method = "qryOrders";
where.body.userId = para.userId;
where.body.pageIdx = para.pageIdx;
where.body.numPerPage = para.numPerPage;
BaseResult<OrdersResult> result = WebAPIHelper<OrdersResult>.Post(where);
return result.body;
}
這樣完成了重復部分代碼的封裝提取,還可以更進一步在WebAPIHelper<T>.POST(obj)方法裡面,添加統一異常處理,如接口服務器異常、超時之類的。
如有不當之處,請大家多多指教。