Example #1
0
 /// <summary>
 /// 同步执行前置过滤器
 /// </summary>
 /// <param name="apiDescriptor"> API描述 </param>
 /// <param name="context"> 上下文 </param>
 /// <param name="filterArgs"> 过滤器集合 </param>
 private static void FiltrationOnExecuting(this ApiDescriptor apiDescriptor, ApiCallContext context, FilterArgs filterArgs)
 {
     foreach (var filter in apiDescriptor.Filters)
     {
         filter.OnExecuting(context, filterArgs);
     }
 }
Example #2
0
 /// <summary>
 /// 警告日志
 /// </summary>
 public static void Warning(this ApiCallContext context, string message, string title = null)
 {
     context?.Logger?.Append(new LogItem
     {
         Context = context,
         Message = message,
         Level   = LogLevel.Warning,
         Title   = title,
     });
 }
Example #3
0
 /// <summary>
 /// 警告日志
 /// </summary>
 public static void Warning(this ApiCallContext context, object data, string title = null)
 {
     context?.Logger?.Append(new LogItem
     {
         Context = context,
         Data    = data,
         Level   = LogLevel.Warning,
         Title   = title,
     });
 }
Example #4
0
 /// <summary>
 /// 致命错误日志
 /// </summary>
 public static void Critical(this ApiCallContext context, Exception exception, string title = null)
 {
     context?.Logger?.Append(new LogItem
     {
         Context   = context,
         Exception = exception,
         Level     = LogLevel.Critical,
         Title     = title,
         Message   = exception?.Message,
     });
 }
Example #5
0
 /// <summary>
 /// 自定义日志
 /// </summary>
 public static void Write(this ApiCallContext context, LogLevel level, string title, string message, object data, Exception exception)
 {
     context?.Logger?.Append(new LogItem
     {
         Context   = context,
         Message   = message ?? exception?.Message,
         Level     = level,
         Title     = title,
         Data      = data,
         Exception = exception,
     });
 }
Example #6
0
 /// <summary>
 /// 异步执行后置过滤器
 /// </summary>
 /// <param name="apiDescriptor"> API描述 </param>
 /// <param name="context"> 上下文 </param>
 /// <param name="filterArgs"> 过滤器集合 </param>
 private static async Task FiltrationOnExecutingAsync(this ApiDescriptor apiDescriptor, ApiCallContext context, FilterArgs filterArgs)
 {
     foreach (var filter in apiDescriptor.Filters)
     {
         var task = filter.OnExecutingAsync(context, filterArgs);
         if (task != null)
         {
             await task;
         }
     }
 }
Example #7
0
 /// <summary>
 /// 触发请求结束事件
 /// </summary>
 /// <param name="context"></param>
 public void OnEndRequest(ApiCallContext context) => EventCaller.Invoke(GlobalEvents.OnBeginRequest, context);
Example #8
0
 /// <summary>
 /// 将API上下文中的 <see cref="Parameters"/> 和 <see cref="Properties"/> 变为只读集合
 /// </summary>
 /// <param name="context"> api上下文 </param>
 public void MakeReadOnlyContext(ApiCallContext context)
 {
     ((NameDictionary)context?.Parameters).MakeReadOnly();
     ((NameDictionary)context?.Properties).MakeReadOnly();
 }
Example #9
0
        /// <summary>
        /// 创建上下文
        /// </summary>
        /// <param name="apiDescriptor"> api描述 </param>
        /// <param name="dataProvider"> 数据提供程序 </param>
        /// <param name="resultUpdater"> 返回值更新程序 </param>
        /// <returns>如果编译失败,返回异常信息</returns>
        public ApiCallContext CreateContext(ApiDescriptor apiDescriptor, IApiDataProvider dataProvider, out IResultUpdater resultUpdater)
        {
            if (ApiCollection.Apis.Contains(apiDescriptor ?? throw new ArgumentNullException(nameof(apiDescriptor))) == false)
            {
                throw new ArgumentException("API描述不属于当前容器", nameof(apiDescriptor));
            }
            var            logger  = Provider.Logger.GetUsableService(false); //获取日志服务
            ApiCallContext context = null;

            try
            {
                var instance = apiDescriptor.Method.IsStatic
                    ? null
                    : dataProvider.GetApiInstance(apiDescriptor) ??
                               Activator.CreateInstance(apiDescriptor.ApiClass.Type);
                resultUpdater = Provider.CreateResultUpdater() ?? new ResultProvider();
                var session = dataProvider.GetSession();
                context = new ApiCallContext(instance, apiDescriptor.Method, resultUpdater, session, logger);
                context.Data["$ResultProvider"] = resultUpdater;
                context.Data["$ApiContainer"]   = this;
                context.Data["$ApiDescriptor"]  = apiDescriptor;

                logger?.Append(new LogItem()
                {
                    Context = context,
                    Level   = LogLevel.Debug,
                    Message = "创建上下文",
                    Title   = "系统",
                });

                if (session != null)
                {
                    EventCaller.Invoke(GlobalEvents.OnBeginRequest, context);
                }

                var parameters = context.Parameters;
                var properties = context.Properties;

                //属性
                if (apiDescriptor.Method.IsStatic == false)
                {
                    foreach (var p in apiDescriptor.Properties)
                    {
                        var result = dataProvider.GetProperty(p);

                        if (result.Error != null && result.Exists)
                        {
                            properties.Add(p.Name, result.Error);
                            resultUpdater.SetException(result.Error);
                            return(context);
                        }

                        if (result.Exists || p.HasDefaultValue == false)
                        {
                            var value = result.Exists ? result.Value : null;
                            if (p.DataModifications.Count > 0)
                            {
                                p.DataModifications.ForEach(it => it.Modifies(ref value, context)); //变更数据
                            }
                            Modifier.Modifies(value, context);
                            if (result.Exists)
                            {
                                properties.Add(p.Name, value);
                                p.Setter(instance, value);
                            }
                            if (p.DataValidations.Count > 0)
                            {
                                var ex = p.DataValidations.FirstOrDefault(it => it.IsValid(value, context) == false)?
                                         .GetException(p.Name, value, context)
                                         ?? Validator.IsValid(value, context, true); //数据验证
                                if (ex != null)
                                {
                                    resultUpdater.SetException(ex);
                                    return(context);
                                }
                            }
                        }
                        else
                        {
                            properties.Add(p.Name, p.DefaultValue);
                            p.Setter(instance, p.DefaultValue);
                        }
                    }
                }

                //参数
                foreach (var p in apiDescriptor.Parameters)
                {
                    if (p.ParameterType == typeof(ISession))
                    {
                        parameters.Add(p.Name, session);
                        continue;
                    }
                    if (p.ParameterType == typeof(ApiCallContext))
                    {
                        parameters.Add(p.Name, context);
                        continue;
                    }
                    if (p.ParameterType == typeof(ILogger))
                    {
                        parameters.Add(p.Name, logger);
                        continue;
                    }

                    var result = dataProvider.GetParameter(p);

                    if (result.Error != null && result.Exists)
                    {
                        parameters.Add(p.Name, result.Error);
                        resultUpdater.SetException(result.Error);
                        return(context);
                    }

                    if (result.Exists)
                    {
                        var value = result.Value;
                        if (p.DataModifications.Count > 0)
                        {
                            p.DataModifications.ForEach(it => it.Modifies(ref value, context)); //变更数据
                        }
                        Modifier.Modifies(value, context);
                        parameters.Add(p.Name, value);
                        if (p.DataValidations.Count > 0)
                        {
                            var ex = p.DataValidations.FirstOrDefault(it => it.IsValid(value, context) == false)?.GetException(p.Name, value, context)
                                     ?? Validator.IsValid(value, context, true); //数据验证
                            if (ex != null)
                            {
                                resultUpdater.SetException(ex);
                                return(context);
                            }
                        }
                    }
                    else if (p.HasDefaultValue)
                    {
                        parameters.Add(p.Name, p.DefaultValue);
                    }
                    else
                    {
                        var ex = ApiException.ArgumentMissing(p.Name);
                        parameters.Add(p.Name, ex);
                        resultUpdater.SetException(ex);
                        return(context);
                    }
                }

                EventCaller.Invoke(GlobalEvents.OnApiDataParsed, context);
                return(context);
            }
            catch (Exception ex)
            {
                logger?.Append(new LogItem()
                {
                    Context   = context,
                    Exception = ex,
                    Level     = LogLevel.Critical,
                    Message   = "未处理异常",
                    Title     = "系统",
                });
                EventCaller.Invoke(GlobalEvents.OnUnprocessException, context);
                throw;
            }
            finally
            {
                if (context?.IsError == true)
                {
                    var ex = context.Exception.GetRealException();
                    if (ex is ApiException e)
                    {
                        context.Warning(e.Message, "逻辑异常");
                        if (e.InnerException != null)
                        {
                            context.Warning(e.InnerException, "内部逻辑异常");
                        }
                        EventCaller.Invoke(GlobalEvents.OnApiException, context);
                    }
                    else
                    {
                        context.Error(context.Exception, "服务器内部错误");
                        EventCaller.Invoke(GlobalEvents.OnUnprocessException, context);
                    }
                }
            }
        }