static async Task <object> ExecuteAsync(ApiExecutingContext excutingContext) { object result = null; var methodInfo = excutingContext.ApiMetadata.ApiDescriptor.Info; var obj = methodInfo.Invoke(excutingContext.Service, excutingContext.Parameters); if (obj is Task task) { if (methodInfo.ReturnType.IsGenericType) { await task.ContinueWith(_task => { result = _task.GetType().GetProperty("Result").GetValue(_task); }); } else { await task; } } else { result = obj; } return(result); }
static async Task <bool> OnExecutingAsync(ApiExecutingContext context) { var continued = true; var filters = context.ApiMetadata.Filters; if (filters.Any(_ => _ is IApiCallFilter)) { var apiCallFilters = filters .Where(_ => _ is IApiCallFilter) .OrderBy(_ => _ is IOrderedFilter o ? o.Order : 0) .Cast <IApiCallFilter>(); foreach (var filter in apiCallFilters) { continued = await filter.OnExecutingAsync(context); if (!continued) { break; } } } return(continued); }
/// <summary> /// /// </summary> /// <param name="call"></param> /// <returns></returns> public async Task CallApi(SignalCall call) { await Clients.Caller.Trace($"Client call [{call.Method}] received"); var context = await BuildContextAsync(call); var authorizationProvider = serviceProvider.GetRequiredService <IAuthorizationProvider>(); if (!await authorizationProvider.CheckAuthorizedAsync(context)) { await Clients.Caller.Error("UnAuthorized"); return; } var parameters = context.ApiMetadata.ApiDescriptor.Info.GetParameters() .Select(_ => #if NETCOREAPP3_0 || NET5_0 System.Text.Json.JsonSerializer.Deserialize(((System.Text.Json.JsonElement)call.Parameters).GetRawText(), _.ParameterType) #else (call.Parameters as Newtonsoft.Json.Linq.JObject)?.ToObject(_.ParameterType) #endif ) .ToArray(); var validationProvider = serviceProvider.GetService <IValidationProvider>(); if (validationProvider != null) { if (!await validationProvider.ValidateAsync(parameters)) { await Clients.Caller.Error("ValidationError", errors : validationProvider.Errors); return; } } try { var service = ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, context.ApiMetadata.ApiDescriptor.Info.DeclaringType) as ApiServiceBase; service.CallContext = context; var excutingContext = new ApiExecutingContext(context, service, parameters); if (!await OnExecutingAsync(excutingContext)) { return; } var result = await ExecuteAsync(excutingContext); var executedContext = new ApiExecutedContext(excutingContext, result); if (!await OnExecutedAsync(executedContext)) { return; } if (!string.IsNullOrEmpty(call.Callback)) { await Clients.Caller.Handle(new SignalResult { Method = call.Callback, Data = executedContext.Result, }); } } catch (Exception exception) { var exceptionContext = new ApiExceptionContext(context, exception); if (await HandleExceptionAsync(exceptionContext)) { await Clients.Caller.Error(exception.Message, exception.HResult); } } }