首先创建了一个单元测试,如下项目视图:
分页结果映射类PageResult的编写:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo { /// <summary> /// 分页结果 /// </summary> /// <typeparam name="T"></typeparam> public class PageResult<T> where T : class { public PageResult() { this.Results = new List<T>(); } /// <summary> /// 页码 /// </summary> public int PageNo { get; set; } /// <summary> /// 页量 /// </summary> public int PageSize { get; set; } /// <summary> /// 条数 /// </summary> public int RecordCount { get; set; } /// <summary> /// 页数 /// </summary> public int PageCount { get; set; } public List<T> Results { get; set; } } /// <summary> /// 原始的返回结果 /// </summary> public class StartReturnResult<T> where T : class { /// <summary> /// 分页结果 /// </summary> public StartPageResult<T> Result { get; set; } /// <summary> /// 总页数 /// </summary> public int TotalPageCount { get; set; } } /// <summary> /// 原始的分页结果 /// </summary> public class StartPageResult<T> where T : class { public StartPageResult() { this.Results = new List<T>(); } /// <summary> /// 开始位置 /// 值始终为0 /// </summary> public int Start { get; set; } /// <summary> /// 每页数量 /// </summary> public int PageSize { get; set; } /// <summary> /// 数据总数 /// </summary> public int TotalCount { get; set; } /// <summary> /// 数据集合 /// </summary> public List<T> Results { get; set; } /// <summary> /// 页码 /// 值始终为1 /// </summary> public int Page { get; set; } /// <summary> /// 页码 /// 值始终为1 /// </summary> public int CurrentPageNo { get; set; } /// <summary> /// 总页数 /// </summary> public int TotalPageCount { get; set; } } }
检索条件SearchCondition如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo { /// <summary> /// 检索条件 /// </summary> public class SearchCondition { /// <summary> /// 检索关键字 /// </summary> public string Keyword { get; set; } /// <summary> /// 检索的页码 /// </summary> public int PageNo { get; set; } } }
Helper文件夹下的DataSerializer类如下:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo.Helpers { /// <summary> /// 数据序列化器 /// </summary> public static class DataSerializer { /// <summary> /// json 序列号 /// </summary> /// <param name="source">要序列化的对象</param> /// <param name="b">是否忽略空值,true为不忽略</param> /// <returns></returns> public static string SerizlizeToJSON(object source,bool b=true) { var setting = new JsonSerializerSettings(); setting.ContractResolver = new SortedContractResolver(); if (!b) { setting.NullValueHandling = NullValueHandling.Ignore; //忽略空对象 } var jsonString = JsonConvert.SerializeObject(source, setting); return jsonString; } public static TData DeserializeFromJSON<TData>(string jsonString) { var data = JsonConvert.DeserializeObject<TData>(jsonString); return data; } } public class SortedContractResolver : DefaultContractResolver { protected override List<MemberInfo> GetSerializableMembers(Type objectType) { var members = base.GetSerializableMembers(objectType); return members.OrderBy(m => m.Name).ToList(); } } }
Helper文件夹下的HttpRequester类如下:
using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Web; namespace ReuqestDemo.Helpers { public static class HttpRequester { public const string CONTENT_TYPE_JSON = "application/json"; public const string CONTENT_TYPE_FORM = "application/x-www-form-urlencoded"; public static async Task<TResult> PostAsync<TResult>(HttpClient client, string url, string dataString, IDictionary<string, string> headers = null) { var rsp = await PostAsync(client, url, dataString, CONTENT_TYPE_FORM, headers); var res = DataSerializer.DeserializeFromJSON<TResult>(rsp); return res; } public static async Task<string> PostAsync(HttpClient client, string url, string dataString, string contentType, IDictionary<string, string> headers = null) { using (HttpContent content = new StringContent(dataString)) { var mt = new MediaTypeHeaderValue(contentType) { CharSet = "UTF-8" }; content.Headers.ContentType = mt; if (headers != null) { foreach (var item in headers) { content.Headers.Add(item.Key, item.Value); } } var rsp = await client.PostAsync(url, content); rsp.EnsureSuccessStatusCode(); var text = await rsp.Content.ReadAsStringAsync(); return text; } } public static string CombinParametersUrlEncode(IEnumerable<KeyValuePair<string, string>> parameters) { return CombinParameters(parameters, true); } private static string CombinParameters(IEnumerable<KeyValuePair<string, string>> parameters, bool isUrlEncode) { var pStr = string.Empty; if (parameters != null) { var pSB = new StringBuilder(); if (isUrlEncode) { foreach (var p in parameters) { pSB.Append(HttpUtility.UrlEncode(p.Key)).Append("=").Append(HttpUtility.UrlEncode(p.Value)).Append("&"); } } else { foreach (var p in parameters) { pSB.Append(p.Key).Append("=").Append(p.Value).Append("&"); } } pStr = pSB.ToString(); } if (string.IsNullOrEmpty(pStr)) return pStr; return pStr.Substring(0, pStr.Length - 1); } } }
Helper文件夹下的TimeHelper类如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo.Helpers { public static class TimeHelper { /// <summary> /// 返回时间戳 /// </summary> /// <returns>时间戳</returns> public static long GetTimeStamp() { TimeSpan tSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(tSpan.TotalMilliseconds); } /// <summary> /// 返回时间戳 /// </summary> /// <returns>时间戳</returns> public static string GetTStamp() { return GetTimeStamp().ToString(); } } }
Models文件夹下的ResultModel类如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo.Models { /// <summary> /// 请求结果图示 /// </summary> public class ResultModel { /// <summary> /// 唯一标识 /// </summary> public string Id { get; set; } /// <summary> /// 公司名称 /// </summary> public string EntName { get; set; } } }
Models文件夹下的SearchArgument类如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ReuqestDemo.Models { /// <summary> /// 检索参数 /// </summary> public class SearchArgument { /// <summary> /// 检索关键字 /// </summary> public string Keyword { get; set; } /// <summary> /// 检索的页码 /// </summary> public int Page { get; set; } public int SearchType { get; set; } } }
CompanyData,用于接口的的实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using System.Threading.Tasks; using ReuqestDemo.Models; using ReuqestDemo.Helpers; namespace ReuqestDemo { public class CompanyData { #region 保护属性 protected HttpClient _client = new HttpClient() { Timeout = new TimeSpan(0, 0, 3) }; #endregion #region 公共方法 /// <summary> /// 分页获取数据 /// </summary> /// <param name="condition">分页检索条件</param> /// <returns></returns> public async Task<PageResult<ResultModel>> GetDataByPage(SearchCondition condition) { #region 参数转换 var arg = new SearchArgument() { Keyword = condition.Keyword, //查询条件 SearchType = 1, Page = condition.PageNo //查询页数,即第几页 }; #endregion var res = await this.GetByPage(arg); return res; } #endregion #region 保护方法 protected async Task<PageResult<ResultModel>> GetByPage(SearchArgument ccsa) { string url = $"。。。。。。"; //发送请求 var data = await HttpRequester.PostAsync<StartReturnResult<ResultModel>>(_client, url, this.getReuestBody(ccsa), this.getRequestHeaders()); //映射结果 var res = this.mappingResult<ResultModel>(data.Result); res.PageNo = ccsa.Page; return res; } #endregion #region 私有方法 private string getReuestBody(SearchArgument ccsa) { var parameters = new Dictionary<string, string>(); parameters.Add("keyword", ccsa.Keyword); parameters.Add("searchtype", ccsa.SearchType.ToString()); parameters.Add("page", ccsa.Page.ToString()); var body = HttpRequester.CombinParametersUrlEncode(parameters); return body; } private IDictionary<string, string> getRequestHeaders() { var headers = new Dictionary<string, string>(); return headers; } /// <summary> /// 映射结果的分页情况 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <returns></returns> private PageResult<T> mappingResult<T>(StartPageResult<T> source) where T : class { var target = new PageResult<T>(); target.PageCount = source.TotalPageCount; target.RecordCount = source.TotalCount; target.Results = source.Results; target.PageSize = source.PageSize; target.PageNo = source.CurrentPageNo; return target; } #endregion } }
单元测试得调用如下:
public void TestMethod1() { var i = new CompanyData(); var res = i.GetDataByPage(new SearchCondition() { Keyword = "一", PageNo = 1 }); Assert.IsNotNull(res); }
如上就是实现了请求的分页获取,上面主要是对比了我写的请求(在之前的对比中有篇”单元测试以文件流的形势传参调用api进行测试“写的请求太过简单),做一个对比,所以需要自己学习的地方,就做了一个demo简单的抽离了出来总结。