예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
                }
            }
        }