WebApi系列~基于单请求封装多请求的设计
怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子请求(真实的请求,接口),这种设计确实看着很灵活,客户端可以根据自己的需要去拿服务器的数据,确实不错!
首先我们要定义一套自己的请求和响应对象
#region 请求对象 /// <summary> /// 参数对象 /// </summary> [DataContractAttribute] public class RequestParam { public RequestParam(string name, string value) { this.ParamName = name; this.ParamValue = value; } [DataMemberAttribute] public string ParamName { get; private set; } [DataMemberAttribute] public string ParamValue { get; private set; } } /// <summary> /// 数据包中的实体 /// </summary> [DataContractAttribute] public class RequestData { public RequestData() { this.HttpMethod = 0; this.RequestParam = new Dictionary<string, string>(); } /// <summary> /// 本次通讯唯一标示 /// </summary> [DataMemberAttribute] public string GuidKey { get; set; } /// <summary> /// 请求方式0:get,1:Post /// </summary> public int HttpMethod { get; set; } /// <summary> /// 要调用的方法 /// </summary> [DataMemberAttribute] public string Url { get; set; } /// <summary> /// 方法的参数列表 /// </summary> [DataMemberAttribute] public IDictionary<string, string> RequestParam { get; set; } } /// <summary> /// 请求数据包 /// </summary> [DataContractAttribute] public class RequestDataSegment { public RequestDataSegment() { this.RequestData = new List<RequestData>(); } [DataMemberAttribute] public List<RequestData> RequestData { get; set; } } #endregion
再来看一下响应对象
#region 响应对象 /// <summary> /// 数据包实体 /// </summary> [DataContractAttribute] public class ResponseData { /// <summary> /// 本次传输过程中唯一标识 /// </summary> [DataMemberAttribute] public string GuidKey { get; set; } /// <summary> /// 状态:100失败,200成功 /// </summary> [DataMemberAttribute] public int Status { get; set; } /// <summary> /// 数据包:Json对象 /// </summary> [DataMemberAttribute] public string Data { get; set; } } /// <summary> /// 响应数据包 /// </summary> [DataContractAttribute] public class ResponseDataSegment { public ResponseDataSegment() { this.ResponseData = new List<ResponseData>(); } [DataMemberAttribute] public List<ResponseData> ResponseData { get; set; } } #endregion
而我们服务器对客户端开放的是一个大接口,或者叫入口接口,它负责把客户端传来的请求进行解析,然后代理客户端,处理多请求,并将结果进行组装,返回给客户端,在mvc和web api里,我们为了让程序扩展性更强,通常把这个核心逻辑写在attribute里
下面看一下代码的实现
/// <summary> /// Api代理过滤器(api多任务请求的入口) /// </summary> [AttributeUsage(AttributeTargets.Method)] public class ApiProxyFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var Request = filterContext.HttpContext.Request; var responseDataSegment = new ResponseDataSegment(); var data = VCommons.SerializeMemoryHelper.DeserializeFromJson<RequestDataSegment>(Request.Form["dataSeg"]); if (data != null && data.RequestData.Any()) { foreach (var item in data.RequestData) { try { HttpResponseMessage response; var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip }; using (var http = new HttpClient(handler)) { if (item.HttpMethod == 0) { if (item.RequestParam != null) { item.Url += "?"; foreach (var p in item.RequestParam) item.Url += p.Key + "=" + p.Value + "&"; item.Url = item.Url.Remove(item.Url.Length - 1, 1); } response = http.GetAsync(item.Url).Result; } else { var content = new FormUrlEncodedContent(item.RequestParam); response = http.PostAsync(item.Url, content).Result; } response.EnsureSuccessStatusCode(); responseDataSegment.ResponseData.Add(new ResponseData { GuidKey = item.GuidKey, Status = 200, Data = response.Content.ReadAsStringAsync().Result }); } } catch (Exception ex) { responseDataSegment.ResponseData.Add(new ResponseData { GuidKey = item.GuidKey, Status = 100, Data = ex.Message }); } } } filterContext.HttpContext.Response.ContentType = "applicatin/json"; filterContext.HttpContext.Response.Write(VCommons.SerializeMemoryHelper.SerializeToJson(responseDataSegment)); base.OnActionExecuting(filterContext); } }
对于你的具体项目,选个主入口,在它上面添加上ApiProxy特性即可
/// <summary> /// Api统一处理的入口 /// </summary> /// <returns></returns> [ApiProxyFilter] public JsonResult Index() { return null; }
现在你就可以去测试你的客户端了,哈哈,看是否把你的单个请求里的(三个请求)转发并为你返回了,呵呵.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2014-05-12 EF架构~二级域名中共享Session