【转】webapi基于单请求封装多请求的设计
标签:member 图片 tin ica att 添加 ESS 状态 attr
怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子请求(真实的请求,接口),这种设计确实看着很灵活,客户端可以根据自己的需要去拿服务器的数据,确实不错!
首先我们要定义一套自己的请求和响应对象
#region 请求对象
///
/// 参数对象
///
[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; }
}
///
/// 数据包中的实体
///
[DataContractAttribute]
public class RequestData
{
public RequestData()
{
this.HttpMethod = 0;
this.RequestParam = new Dictionary();
}
///
/// 本次通讯唯一标示
///
[DataMemberAttribute]
public string GuidKey { get; set; }
///
/// 请求方式0:get,1:Post
///
public int HttpMethod { get; set; }
///
/// 要调用的方法
///
[DataMemberAttribute]
public string Url { get; set; }
///
/// 方法的参数列表
///
[DataMemberAttribute]
public IDictionary RequestParam { get; set; }
}
///
/// 请求数据包
///
[DataContractAttribute]
public class RequestDataSegment
{
public RequestDataSegment()
{
this.RequestData = new List();
}
[DataMemberAttribute]
public List RequestData { get; set; }
}
#endregion
再来看一下响应对象
#region 响应对象
///
/// 数据包实体
///
[DataContractAttribute]
public class ResponseData
{
///
/// 本次传输过程中唯一标识
///
[DataMemberAttribute]
public string GuidKey { get; set; }
///
/// 状态:100失败,200成功
///
[DataMemberAttribute]
public int Status { get; set; }
///
/// 数据包:Json对象
///
[DataMemberAttribute]
public string Data { get; set; }
}
///
/// 响应数据包
///
[DataContractAttribute]
public class ResponseDataSegment
{
public ResponseDataSegment()
{
this.ResponseData = new List();
}
[DataMemberAttribute]
public List ResponseData { get; set; }
}
#endregion
而我们服务器对客户端开放的是一个大接口,或者叫入口接口,它负责把客户端传来的请求进行解析,然后代理客户端,处理多请求,并将结果进行组装,返回给客户端,在mvc和web api里,我们为了让程序扩展性更强,通常把这个核心逻辑写在attribute里
下面看一下代码的实现
///
/// Api代理过滤器(api多任务请求的入口)
///
[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(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特性即可
///
/// Api统一处理的入口
///
///
[ApiProxyFilter]
public JsonResult Index()
{
return null;
}
现在你就可以去测试你的客户端了,哈哈,看是否把你的单个请求里的(三个请求)转发并为你返回了,呵呵.
【转】webapi基于单请求封装多请求的设计
标签:member 图片 tin ica att 添加 ESS 状态 attr
原文地址:https://www.cnblogs.com/fanfan-90/p/12046576.html
评论