请求Url返回数据较大,使结果分页获取

                   首先创建了一个单元测试,如下项目视图:

                    

                   分页结果映射类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; }
    }
}
View Code

                    检索条件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; }
    }
}
View Code

                     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();
        }
    }
}
View Code

                     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);
        }
    }
}
View Code

                     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();
        }
    }
}
View Code

                     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; }

    }
}
View Code

                     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; }
    }
}
View Code

                    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
    }
}
View Code

                    单元测试得调用如下:

        public void TestMethod1()
        {
            var i = new CompanyData();
            var res = i.GetDataByPage(new SearchCondition() { Keyword = "", PageNo = 1 });
            Assert.IsNotNull(res);
        }

                    如上就是实现了请求的分页获取,上面主要是对比了我写的请求(在之前的对比中有篇”单元测试以文件流的形势传参调用api进行测试“写的请求太过简单),做一个对比,所以需要自己学习的地方,就做了一个demo简单的抽离了出来总结。

posted @ 2017-08-30 19:43  雪?  阅读(1244)  评论(1编辑  收藏  举报