| 
						
						
						
					 | 
				
				 | 
				
					@ -1,11 +1,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using Apewer.Network; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using Apewer.Source; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System.Collections.Generic; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System.Diagnostics; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System.IO; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System.Net; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using System.Reflection; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using static Apewer.Web.ApiUtility; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -21,8 +17,7 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        internal Action<ApiCatch> Catcher = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ApiOptions Options = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Stopwatch Stopwatch = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        DateTime Begin = DateTime.UtcNow; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Uri Url = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        HttpMethod Method = HttpMethod.NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ApiRequest ApiRequest = null; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -36,31 +31,21 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        public string Run() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Options == null) Options = new ApiOptions(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Options.WithDuration) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Stopwatch = new Stopwatch(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Stopwatch.Start(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            var error = Flow(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Stopwatch != null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Stopwatch.Stop(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Stopwatch = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return error; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        string Flow() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 传入字段。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Provider == null) return "服务程序无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Invoker == null) return "调用器无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Entries == null) return "入口无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            Options = Invoker.Options ?? new ApiOptions(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            Provider.Options = Options; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            try | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 传入字段。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (Provider == null) return "服务程序无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (Invoker == null) return "调用器无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (Entries == null) return "入口无效。"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Options = Invoker.Options ?? new ApiOptions(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Provider.Options = Options; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 检查执行的前提条件,获取 Method 和 URL。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                var check = Check(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (!string.IsNullOrEmpty(check)) return check; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -77,28 +62,36 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (!string.IsNullOrEmpty(invoke)) return invoke; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 输出。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (Stopwatch != null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Stopwatch.Stop(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ApiResponse.Duration = Stopwatch.ElapsedMilliseconds; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Stopwatch = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                ApiResponse.Duration = Duration(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Output(Provider, Options, ApiResponse, ApiRequest, Method); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            catch (Exception ex) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (Stopwatch != null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Stopwatch.Stop(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Stopwatch = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                var message = ex.Message(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Logger.Internals.Error(typeof(ApiInvoker), message); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return message; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        string Duration() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            var span = DateTime.UtcNow - Begin; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            var ms = span.TotalMilliseconds; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (ms > 0D) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                var s = span.TotalMilliseconds / 1000D; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (s > 10D) return Math.Round(s, 1).ToString() + "s"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (s > 1D) return Math.Round(s, 2).ToString() + "s"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (ms > 10D) return Math.Round(ms, 0).ToString() + "ms"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return Math.Round(ms, 1).ToString() + "ms"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        string Check() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 服务程序检查。
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -147,7 +140,7 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            Invoke(Entries.Get(appName)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (Stopwatch != null) ApiResponse.Duration = Stopwatch.ElapsedMilliseconds; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ApiResponse.Duration = Duration(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ApiResponse.Application = appName; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ApiResponse.Function = funcName; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ApiResponse.Random = random; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -489,7 +482,7 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 包含 API 的处理时间。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (options.WithDuration && response != null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    merged.Add("Duration", response.Duration.ToString() + "ms"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (response.Duration.NotEmpty()) merged.Add("Duration", response.Duration); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (response != null) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -534,7 +527,7 @@ namespace Apewer.Web | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 持续时间。
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (options.WithDuration) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                json.SetProperty("duration", response.Duration); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (response.Duration.NotEmpty()) json.SetProperty("duration", response.Duration); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 随机值。
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |