首先创建了一个单元测试,如下项目视图:
分页结果映射类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(, pStr.Length - );
}
}
}
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(, , , , , , );
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(, , ) }; #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 = ,
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 = });
Assert.IsNotNull(res);
}
如上就是实现了请求的分页获取,上面主要是对比了我写的请求(在之前的对比中有篇”单元测试以文件流的形势传参调用api进行测试“写的请求太过简单),做一个对比,所以需要自己学习的地方,就做了一个demo简单的抽离了出来总结。