你的位置:首页 > ASP.net教程

[ASP.net教程]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;    }

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