怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子请求(真实的请求,接口),这种设计确实看着很灵活,客户端可以根据自己的需要去拿服务器的数据,确实不错!

首先我们要定义一套自己的请求和响应对象

 
  1. #region 请求对象
  2. /// <summary>
  3. /// 参数对象
  4. /// </summary>
  5. [DataContractAttribute]
  6. public class RequestParam
  7. {
  8. public RequestParam(string name, string value)
  9. {
  10. this.ParamName = name;
  11. this.ParamValue = value;
  12. }
  13. [DataMemberAttribute]
  14. public string ParamName { get; private set; }
  15. [DataMemberAttribute]
  16. public string ParamValue { get; private set; }
  17. }
  18. /// <summary>
  19. /// 数据包中的实体
  20. /// </summary>
  21. [DataContractAttribute]
  22. public class RequestData
  23. {
  24. public RequestData()
  25. {
  26. this.HttpMethod = 0;
  27. this.RequestParam = new Dictionary<string, string>();
  28. }
  29. /// <summary>
  30. /// 本次通讯唯一标示
  31. /// </summary>
  32. [DataMemberAttribute]
  33. public string GuidKey { get; set; }
  34. /// <summary>
  35. /// 请求方式0:get,1:Post
  36. /// </summary>
  37. public int HttpMethod { get; set; }
  38. /// <summary>
  39. /// 要调用的方法
  40. /// </summary>
  41. [DataMemberAttribute]
  42. public string Url { get; set; }
  43. /// <summary>
  44. /// 方法的参数列表
  45. /// </summary>
  46. [DataMemberAttribute]
  47. public IDictionary<string, string> RequestParam { get; set; }
  48. }
  49. /// <summary>
  50. /// 请求数据包
  51. /// </summary>
  52. [DataContractAttribute]
  53. public class RequestDataSegment
  54. {
  55. public RequestDataSegment()
  56. {
  57. this.RequestData = new List<RequestData>();
  58. }
  59. [DataMemberAttribute]
  60. public List<RequestData> RequestData { get; set; }
  61. }
  62. #endregion
 

再来看一下响应对象

 
  1. #region 响应对象
  2. /// <summary>
  3. /// 数据包实体
  4. /// </summary>
  5. [DataContractAttribute]
  6. public class ResponseData
  7. {
  8. /// <summary>
  9. /// 本次传输过程中唯一标识
  10. /// </summary>
  11. [DataMemberAttribute]
  12. public string GuidKey { get; set; }
  13. /// <summary>
  14. /// 状态:100失败,200成功
  15. /// </summary>
  16. [DataMemberAttribute]
  17. public int Status { get; set; }
  18. /// <summary>
  19. /// 数据包:Json对象
  20. /// </summary>
  21. [DataMemberAttribute]
  22. public string Data { get; set; }
  23. }
  24. /// <summary>
  25. /// 响应数据包
  26. /// </summary>
  27. [DataContractAttribute]
  28. public class ResponseDataSegment
  29. {
  30. public ResponseDataSegment()
  31. {
  32. this.ResponseData = new List<ResponseData>();
  33. }
  34. [DataMemberAttribute]
  35. public List<ResponseData> ResponseData { get; set; }
  36. }
  37. #endregion
 

而我们服务器对客户端开放的是一个大接口,或者叫入口接口,它负责把客户端传来的请求进行解析,然后代理客户端,处理多请求,并将结果进行组装,返回给客户端,在mvc和web api里,我们为了让程序扩展性更强,通常把这个核心逻辑写在attribute里

下面看一下代码的实现 

 
  1. /// <summary>
  2. /// Api代理过滤器(api多任务请求的入口)
  3. /// </summary>
  4. [AttributeUsage(AttributeTargets.Method)]
  5. public class ApiProxyFilter : ActionFilterAttribute
  6. {
  7. public override void OnActionExecuting(ActionExecutingContext filterContext)
  8. {
  9. var Request = filterContext.HttpContext.Request;
  10. var responseDataSegment = new ResponseDataSegment();
  11. var data = VCommons.SerializeMemoryHelper.DeserializeFromJson<RequestDataSegment>(Request.Form["dataSeg"]);
  12. if (data != null && data.RequestData.Any())
  13. {
  14. foreach (var item in data.RequestData)
  15. {
  16. try
  17. {
  18. HttpResponseMessage response;
  19. var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
  20. using (var http = new HttpClient(handler))
  21. {
  22.  
  23. if (item.HttpMethod == 0)
  24. {
  25. if (item.RequestParam != null)
  26. {
  27. item.Url += "?";
  28. foreach (var p in item.RequestParam)
  29. item.Url += p.Key + "=" + p.Value + "&";
  30. item.Url = item.Url.Remove(item.Url.Length - 1, 1);
  31. }
  32. response = http.GetAsync(item.Url).Result;
  33. }
  34. else
  35. {
  36. var content = new FormUrlEncodedContent(item.RequestParam);
  37. response = http.PostAsync(item.Url, content).Result;
  38. }
  39.  
  40. response.EnsureSuccessStatusCode();
  41. responseDataSegment.ResponseData.Add(new ResponseData
  42. {
  43. GuidKey = item.GuidKey,
  44. Status = 200,
  45. Data = response.Content.ReadAsStringAsync().Result
  46. });
  47. }
  48. }
  49. catch (Exception ex)
  50. {
  51.  
  52. responseDataSegment.ResponseData.Add(new ResponseData
  53. {
  54. GuidKey = item.GuidKey,
  55. Status = 100,
  56. Data = ex.Message
  57. });
  58. }
  59.  
  60. }
  61.  
  62. }
  63. filterContext.HttpContext.Response.ContentType = "applicatin/json";
  64. filterContext.HttpContext.Response.Write(VCommons.SerializeMemoryHelper.SerializeToJson(responseDataSegment));
  65. base.OnActionExecuting(filterContext);
  66. }
  67. }

对于你的具体项目,选个主入口,在它上面添加上ApiProxy特性即可

  1.      /// <summary>
  2. /// Api统一处理的入口
  3. /// </summary>
  4. /// <returns></returns>
  5. [ApiProxyFilter]
  6. public JsonResult Index()
  7. {
  8. return null;
  9. }

现在你就可以去测试你的客户端了,哈哈,看是否把你的单个请求里的(三个请求)转发并为你返回了,呵呵.

webapi基于单请求封装多请求的设计【转】的更多相关文章

  1. WebApi系列~基于单请求封装多请求的设计

    回到目录 怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能 ...

  2. drf:restful概念,类继承关系,drf请求封装,drf请求流程,版本控制组件,认证组件(token),权限组件

    1.restful规范 resfful规范的概念最重要: 是一套规范,规则,用于程序之间进行数据交换的约定. 他规定了一些协议,对我们感受最直接的就是,以前写增删改查的时候需要些四个视图寒素,rest ...

  3. WebApi系列~基于单请求封装多请求的设计~请求的安全性设计与实现

    回到目录 对于一个Http请求如何保证它的安全,这已经不是一个新的话题,对于请求的安全我们通常考虑的无非就是"请求的被篡改性"和"请求的被复制性",第一个问题我们很容易实现,可以通过参数+密钥的方式, ...

  4. Flutter 实际开发常用工具类(全局提示,请求封装,token缓存,验证码倒计时、常用窗帘动画及布局)

    介绍: 一星期从入门到实际开发经验分享及总结           代码传送门github Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.未来App开发 ...

  5. 简单的基于Vue-axios请求封装

    具体实现思路=>封装之前需要用npm安装并引入axios,使用一个单独的js模块作为接口请输出对象,然后export dafult 这个对象. 1.首先我们需要在Vue实例的原型prototyp ...

  6. uniapp 基于 flyio 的 http 请求封装

    之前写请求都是用别人封装好的,直接 import request 完事,自己第一次写还是一头雾水,学习了一波搞清楚了些,可以写简单的封装了. 首先要搞清楚为什么封装请求,同其他的封装一样,我们把不同请 ...

  7. 基于 fetch 的请求封装

    原生 fetch 请求失败后(如无网络)状态会变成 reject 走 .catch .绝大多数情况下业务场景只需要给个 toast 等简单处理.每个请求都 .catch 会显得格外繁琐,并且如果不 . ...

  8. iOS开发--Swift 基于AFNetworking 3.0的网络请求封装

    Swift和OC基于AFNetworking的网络请求流程相同, 就是语法不同, 对于Swift语法不是很清楚的同学, 建议多看看API文档, 自己多多尝试. 写过OC的应该都明白每句话做什么的, 就 ...

  9. 转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)

    http://blog.csdn.net/kroclin/article/details/40540761 一.前言 volley的发布让网络请求也变得十分便利,但是我们通常懒得很想用一两句代码实现一 ...

随机推荐

  1. 小测试整理(含T1 T2)

    这次测试规模较小,前两题也较水,但需要整理 T1(Jelly的男♂难题1): 从一个点出发,以四连通的方式扩散,可以走#,不能走o,走过的格子每单位时间会增加1点高度,问扩散完整间屋子需要的时间,以及 ...

  2. Java 并发系列之十三:安全发布

    1. 定义 发布对象(Publish): 使一个对象能够被当前范围之外的代码所使用 对象逸出(Escape): 一种错误的发布.当一个对象还没有构造完成时,就使它被其他线程所见 1.1 发布对象 pu ...

  3. 把ping的结果写入文件

    写一个sh文件: #!/bin/bash while true do $|>&` done 保存成ping.sh,赋可执行权限: chmod +x ping.sh 执行: sh ./pi ...

  4. ThinkPHP查询数据的时候toArray()报错解决办法

    当查找不到数据时toArray()会报错,如图 解决办法:先查找数据,然后加个判断,如果有数据再转化为数组,如果没有数据就给个空值,不想代码继续往下执行就return false;

  5. UVA 291 The House Of Santa Claus DFS

    题目: In your childhood you most likely had to solve the riddle of the house of Santa Claus. Do you re ...

  6. C# 中如何创建异步平行任务?

    解释都在代码里,直接贴代码了: private async void btnStartRequestResource_Click(object sender, EventArgs e) { ShowA ...

  7. Gitlab 备份还原/迁移

    Gitlab 备份还原 备份数据:通过命令进行备份操作 gitlab-rake gitlab:backup:create ... [DISABLED] Creating backup archive: ...

  8. 2019-11-29-dotnet-core-使用-GBK-编码

    原文:2019-11-29-dotnet-core-使用-GBK-编码 title author date CreateTime categories dotnet core 使用 GBK 编码 li ...

  9. 2019-11-29-win10-uwp-列表模板选择器

    原文:2019-11-29-win10-uwp-列表模板选择器 title author date CreateTime categories win10 uwp 列表模板选择器 lindexi 20 ...

  10. C# 三元表达式

    一.背景 因编程的基础差,因此最近开始巩固学习C#基础,后期把自己学习的东西,总结相应文章中,有不足处请大家多多指教. 二.语法 表达式1?表达式2:表达式3 描述: 表达式1一般为一个关系表达式. ...