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

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

时间: 2024-11-09 17:41:35

WebApi系列~基于单请求封装多请求的设计的相关文章

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

对于一个Http请求如何保证它的安全,这已经不是一个新的话题,对于请求的安全我们通常考虑的无非就是"请求的被篡改性"和"请求的被复制性",第一个问题我们很容易实现,可以通过参数+密钥的方式,而第二个问题就很难实现了,到目前为止也没有一个统一的标准,今天我们要说的安全性,也主要针对的第一种来讲的. 对于一个URL地址来说,可能是这样的格式 http://www.domain.com?vid=1&type=3&main=ok 对上面地址进行安全防篡改之后,可能地址就变成了这样 http://w

【转】webapi基于单请求封装多请求的设计

怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子请求(真实的请求,接口),这种设计确实看着很灵活,客户端可以根据自己的需要去拿服务器的数据,确实不错! 首先我们要定义一套自己的请求和响应对象 #region 请求对象 /// <summary> /// 参数对象 /// </summary> [DataContractAttribu

WebApi系列~基于RESTful标准的Web Api

WebApi系列~基于RESTful标准的Web Api 回到目录 微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码可读性强的,上手快的,如果要拿它和web服务相比,我会说,它的接口更标准,更清晰,没有混乱的方法名称,有的只有几种标准的请求,如get,post,put,delete等,它们分别对应的几个操作,下面讲一下: GET:生到数据列表(默

mbed系列--基于飞思卡尔FRDM KL25Z的鼠标设计快速实现

========================================================== 原创文章转载请注明:blog.csdn.net/guo8113 ========================================================================== 说明: 今天接着上次的mbed工程又玩弄了一番,实现了基于mbed RTOS以及三轴重力传感器的鼠标,当然了,由于FRDM25Z上没有按键,仅仅实现了鼠标的移动. 在这

WebApi系列~目录

回到占占推荐博客索引 写了这个系列的文章不少了,也应该为大家写个目录了,最近很刮了很多SOA的风,很多企业都将自己的系统进行分割,通常是按模块进行拆分,为这个模块提供统一的接口提供业务服务,这不紧可以提高代码重用,也更好了扩展了其它服务,如为第三方提供一些数据,也可以通过这种soa模式来实现. WebApi系列~目录 WebApi系列~基于RESTful标准的Web Api (2014-02-19 13:30) WebApi系列~在WebApi中实现Cors访问 (2014-02-20 10:3

Flutter中的单例以及网络请求库的封装

https://zhuanlan.zhihu.com/p/53498914 Flutter中的单例以及网络请求库的封装 ClassNotFound 程序员 25 人赞同了该文章 Why?为什么需要单例 在Android中我们经常使用OkHttp来进行网络请求,但我们并不希望每次都创建一个OkHttpClient:亦或有些资源初始化非常麻烦,消耗性能,我们希望一次创建,处处使用.这时候就需要单例.Dio作为flutter中的OkHttp,我们也可以用单例模式对其进行封装. How?如何用dart实

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

http://blog.csdn.net/kroclin/article/details/40540761 一.前言 volley的发布让网络请求也变得十分便利,但是我们通常懒得很想用一两句代码实现一个网络请求,其实你再经过封装就可以做到的.还有就是实际开发当中,我们会常常遇到很多异常情况,如网络异常.超时异常等等,那么我们如果有10个activity需要请求数据,那么在10个activity当中都去处理这些异常就变得十分麻烦,通过合理的设计其实我们能够在一个地方对异常情况进行统一处理,只有正确

微信公众号开发系列-Http请求封装基类

HttpHelper请求封装基类,支持get请求和POS请求,方便微信开发接口交互,为后面接口交互做准备. 1.HttpHelper帮助基类 [csharp] view plaincopy using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Net; using System.Net.Security; namespa

LXNetwork – 基于AF3.0封装的iOS网络请求库

本框架实现思路与YTKNetwork和RTNetworking类似,相当于一个简单版,把每一个网络请求封装成对象.使用LXNetwork,你的每一个请求都需要继承LXBaseRequest类,通过覆盖父类的一些方法或者实现相关协议方法来构造指定的网络请求.这个网络库可直接在项目中使用,但是有些功能完成度不是很完美,待完善. GitHud地址:https://github.com/CoderLXWang/LXNetwork 一.为什么要这样做? 实现思路的图在下面,可以对比着图看下面内容. 直接封