你的位置:首页 > ASP.net教程

[ASP.net教程]用泛型减少重复代码,使代码更合理、更优雅


有这样一个场景,需要对接接口,以获取取得数据。

例如获取订单列表

接口请求参数(json格式):

 1 { 2   //公共头部 3   "head":{ 4     "method":"getOrders",    //接口方法 5     "sign":"xxxx"        //签名 6   }, 7   //私有主体 8   "body":{ 9     "userId":"1",        //用户ID10     "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":value18     省略...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 headBaseWhere27 {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 headBaseResult25 {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 OrdersResult17 {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     try18     {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     try40     {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)方法里面,添加统一异常处理,如接口服务器异常、超时之类的。

如有不当之处,请大家多多指教。