/// <summary>执行</summary> /// <param name="session">会话</param> /// <param name="action">动作</param> /// <param name="args">参数</param> /// <param name="msg">消息</param> /// <returns></returns> public virtual Object Execute(IApiSession session, String action, Packet args, IMessage msg) { if (action.IsNullOrEmpty()) { action = "Api/Info"; } var api = session.FindAction(action); if (api == null) { throw new ApiException(404, "无法找到名为[{0}]的服务!".F(action)); } // 全局共用控制器,或者每次创建对象实例 var controller = session.CreateController(api); if (controller == null) { throw new ApiException(403, "无法创建名为[{0}]的服务!".F(api.Name)); } if (controller is IApi capi) { capi.Session = session; } if (session is INetSession ss) { api.LastSession = ss.Remote + ""; } else { api.LastSession = session + ""; } var st = api.StatProcess; var sw = st.StartCount(); var ctx = Prepare(session, action, args, api, msg); ctx.Controller = controller; Object rs = null; try { // 执行动作前的过滤器 if (controller is IActionFilter filter) { filter.OnActionExecuting(ctx); rs = ctx.Result; } // 执行动作 if (rs == null) { // 特殊处理参数和返回类型都是Packet的服务 if (api.IsPacketParameter && api.IsPacketReturn) { var func = api.Method.As <Func <Packet, Packet> >(controller); rs = func(args); } else if (api.IsPacketParameter) { rs = controller.Invoke(api.Method, args); } else { var ps = ctx.ActionParameters; rs = controller.InvokeWithParams(api.Method, ps as IDictionary); } ctx.Result = rs; } // 执行动作后的过滤器 if (controller is IActionFilter filter2) { filter2.OnActionExecuted(ctx); rs = ctx.Result; } } catch (ThreadAbortException) { throw; } catch (Exception ex) { ctx.Exception = ex.GetTrue(); // 执行动作后的过滤器 if (controller is IActionFilter filter) { filter.OnActionExecuted(ctx); rs = ctx.Result; } if (ctx.Exception != null && !ctx.ExceptionHandled) { throw; } } finally { // 重置上下文,待下次重用对象 ctx.Reset(); st.StopCount(sw); } return(rs); }
/// <summary>执行</summary> /// <param name="session"></param> /// <param name="action"></param> /// <param name="args"></param> /// <returns></returns> public Object Execute(IApiSession session, String action, Packet args) { var api = session.FindAction(action); if (api == null) { throw new ApiException(404, "无法找到名为[{0}]的服务!".F(action)); } // 全局共用控制器,或者每次创建对象实例 var controller = session.CreateController(api); if (controller == null) { throw new ApiException(403, "无法创建名为[{0}]的服务!".F(api.Name)); } if (controller is IApi capi) { capi.Session = session; } var enc = Host.Encoder; IDictionary <String, Object> ps = null; // 上下文 var ctx = new ControllerContext { Controller = controller, Action = api, ActionName = action, Session = session, Request = args, }; // 当前上下文 ControllerContext.Current = ctx; // 如果服务只有一个二进制参数,则走快速通道 var fast = api.IsPacketParameter && api.IsPacketReturn; if (!fast) { // 不允许参数字典为空 var dic = args == null || args.Total == 0 ? new NullableDictionary <String, Object>(StringComparer.OrdinalIgnoreCase) : enc.Decode(action, args) as IDictionary <String, Object>; ctx.Parameters = dic; // 准备好参数 ps = GetParams(api.Method, dic, enc); ctx.ActionParameters = ps; } Object rs = null; try { // 执行动作前的过滤器 if (controller is IActionFilter filter) { filter.OnActionExecuting(ctx); rs = ctx.Result; } // 执行动作 if (rs == null) { if (fast) { var func = api.Method.As <Func <Packet, Packet> >(controller); rs = func(args); } else { // 特殊处理参数和返回类型都是Packet的服务 rs = controller.InvokeWithParams(api.Method, ps as IDictionary); } ctx.Result = rs; } } catch (ThreadAbortException) { throw; } catch (Exception ex) { //rs = OnException(ctx, ex); ctx.Exception = ex.GetTrue(); } finally { // 执行动作后的过滤器 if (controller is IActionFilter filter) { filter.OnActionExecuted(ctx); rs = ctx.Result; } ControllerContext.Current = null; if (ctx.Exception != null && !ctx.ExceptionHandled) { throw ctx.Exception; } } //// 二进制优先通道 //if (api.IsPacketReturn && rs is Packet pk) return pk; return(rs); }
/// <summary>执行</summary> /// <param name="session"></param> /// <param name="action"></param> /// <param name="args"></param> /// <returns></returns> public Object Execute(IApiSession session, String action, IDictionary <String, Object> args) { var api = session.FindAction(action); if (api == null) { throw new ApiException(404, "无法找到名为[{0}]的服务!".F(action)); } // 全局共用控制器,或者每次创建对象实例 var controller = session.CreateController(api); if (controller == null) { throw new ApiException(403, "无法创建名为[{0}]的服务!".F(api.Name)); } if (controller is IApi) { (controller as IApi).Session = session; } // 服务端需要检查登录授权 var svrHost = Host as ApiServer; if (svrHost != null && !svrHost.Anonymous) { if (controller.GetType().GetCustomAttribute <AllowAnonymousAttribute>() == null && api.Method.GetCustomAttribute <AllowAnonymousAttribute>() == null) { if (session.UserSession == null || !session.UserSession.Logined) { throw new ApiException(401, "未登录!"); } } } // 服务设置优先于全局主机 var svr = session.GetService <IApiServer>(); var enc = svr?.Encoder ?? Host.Encoder; // 全局过滤器、控制器特性、Action特性 var fs = api.ActionFilters; // 控制器实现了过滤器接口 if (controller is IActionFilter) { var list = fs.ToList(); list.Add(controller as IActionFilter); fs = list.ToArray(); } // 不允许参数字典为空 if (args == null) { args = new NullableDictionary <String, Object>(StringComparer.OrdinalIgnoreCase); } else { args = args.ToNullable(StringComparer.OrdinalIgnoreCase); } // 准备好参数 var ps = GetParams(api.Method, args, enc); // 上下文 var ctx = new ControllerContext { Controller = controller, Action = api, Session = session, Parameters = args }; Object rs = null; ExceptionContext etx = null; try { // 当前上下文 var actx = new ActionExecutingContext(ctx) { ActionParameters = ps }; ControllerContext.Current = actx; // 执行动作前的过滤器 OnExecuting(actx, fs); rs = actx.Result; // 执行动作 if (rs == null) { rs = controller.InvokeWithParams(api.Method, ps as IDictionary); } } catch (ThreadAbortException) { throw; } catch (Exception ex) { // 过滤得到内层异常 ex = ex.GetTrue(); var efs = api.ExceptionFilters; // 控制器实现了异常过滤器接口 if (controller is IExceptionFilter) { var list = efs.ToList(); list.Add(controller as IExceptionFilter); efs = list.ToArray(); } // 执行异常过滤器 etx = OnException(ctx, ex, efs, rs); Host.WriteLog("执行{0}出错!{1}", action, ex.Message); // 如果异常没有被拦截,继续向外抛出 if (!etx.ExceptionHandled) { throw; } return(rs = etx.Result); } finally { // 执行动作后的过滤器 rs = OnExecuted(ctx, etx, fs, rs); ControllerContext.Current = null; } return(rs); }