文章出處

回到目錄

怎么說,單請求封裝多請求,這句話確實有點繞了,但還是要看清楚,想明白這到底是怎么一回事,單請求即一次請求(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;
        }

現在你就可以去測試你的客戶端了,哈哈,看是否把你的單個請求里的(三個請求)轉發并為你返回了,呵呵.

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()