Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }