static async Task <bool> HandleExceptionAsync(ApiExceptionContext context) { var continued = true; var filters = context.ApiMetadata.Filters; if (filters.Any(_ => _ is IExceptionFilter)) { var exceptionFilters = filters .Where(_ => _ is IExceptionFilter) .OrderBy(_ => _ is IOrderedFilter o ? o.Order : 0) .Cast <IExceptionFilter>(); foreach (var filter in exceptionFilters) { continued = await filter.HandleAsync(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); } } }