首先在需要的地方,引入Serialize.Linq对Lambda表达式进行序列化和反序列化处理。
为了更好通用的实现Lambda表达式的正常序列化为文本,以及对文本的反序列化到Lambda表达式,我们这里编写了一个扩展函数,以便更方便的处理。
/// <summary> /// 对Lambda表达式的序列号和反序列化处理 /// </summary> public static class SerializeExtension { /// <summary> /// 序列化 LINQ Expression 表达式为JSON文本 /// </summary> /// <typeparam name="TEntity">处理对象类型</typeparam> /// <typeparam name="TResult">返回结果类型</typeparam> /// <param name="express"></param> /// <returns></returns> public static string SerializeText<TEntity, TResult>(this Expression<Func<TEntity, TResult>> express) { //使用Serialize.Linq组件序列化表达式,传递给API端,API端需要对应反序列化的处理操作进行转换Expression var serializer = new ExpressionSerializer(new JsonSerializer()); var expressJson = serializer.SerializeText(express); //接收端的反序列化处理 //var express = (Expression<Func<TEntity, TResult>>)serializer.DeserializeText(expressJson); return expressJson; } /// <summary> /// 反序列化JSON文本为LINQ Expression 表达式 /// </summary> /// <typeparam name="TEntity">处理对象类型</typeparam> /// <typeparam name="TResult">返回结果类型</typeparam> /// <param name="text"></param> /// <returns></returns> public static Expression<Func<TEntity, TResult>> DeserializeText<TEntity, TResult>(this string json) { Expression<Func<TEntity, TResult>> express = null; if (!string.IsNullOrWhiteSpace(json)) { var serializer = new ExpressionSerializer(new JsonSerializer()); express = (Expression<Func<TEntity, TResult>>)serializer.DeserializeText(json); } return express; } }
这样我们来看看两个对Lambda表达式的Web API代理类的封装处理代码
/// <summary> /// 根据条件,获取所有记录 /// </summary> public virtual async Task<ListResultDto<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> input, string orderBy = null) { var express = input.SerializeText(); //使用扩展函数处理生成JSON var postData = new { express, orderBy }; return await DoActionAsync<ListResultDto<TEntity>>("all-expression", postData, HttpVerb.Post); } /// <summary> /// 根据条件计算记录数量 /// </summary> /// <returns></returns> public virtual async Task<long> CountAsync(Expression<Func<TEntity, bool>> input) { var expressJson = input.SerializeText(); //使用扩展函数处理生成JSON return await DoActionAsync<long>("count-expression", expressJson, HttpVerb.Post); }
而对应的在Web API的基类控制器中,我们对这个通用的实现处理下就可以了
/// <summary> /// 根据条件,获取所有记录 /// </summary> [HttpPost] [Route("all-expression")] public async Task<ListResultDto<TEntity>> GetAllAsync(ExpressionOrderDto input) { ListResultDto<TEntity>? result = null; string json = input.expression; var express = json.DeserializeText<TEntity, bool>(); if (express != null) { result = await _service.GetAllAsync(express!); } return result; } [HttpPost] [Route("count-expression")] public virtual async Task<long> CountAsync(dynamic expressJson) { long result = 0; string json = expressJson; var express = json.DeserializeText<TEntity, bool>(); if (express != null) { result = await _service.CountAsync(express!); } return result; }
这样在服务器端的Web API控制器上,就还原了原先的Lambda表达式,可以正常的接收到客户端提交的条件处理了。
通过这样的迂回的方式,我们就可以在常规的接口,以及Web API的代理类中,都可以使用到Lambda表达式带来的便利性了,而不需要为了兼容而抛弃Lambda表达式接口参数的方式了。
我们可以把其中相关的Lambda表达式,放在一个区块中,方便查看和处理,如下代码所示是在服务端的Web API控制器的基类函数处理代码。