コード例 #1
0
        public async Task CallApi(SignalCall call)
        {
            await Clients.Caller.Trace($"Client call [{call.Method}] received");

            var data = call.Parameters == null ? new ApiRequest() :
                       JsonSerializer.Deserialize <ApiRequest>(((JsonElement)call.Parameters).GetRawText());

            data.Headers.Add(HeaderKeys.ConnectionId, new[] { Context.ConnectionId });

            try
            {
                var request  = CreateRequest(call.Method, data.HttpMethod, data.Headers, data.Body);
                var response = await GetResponse(request);

                await Clients.Caller.Trace($"Client call [{call.Method}] done: {response.StatusCode}");

                if (response.IsSuccessStatusCode)
                {
                    if (!string.IsNullOrEmpty(call.Callback))
                    {
                        await Clients.Caller.Handle(new SignalResult
                        {
                            Method = call.Callback,
                            Data   = new
                            {
                                Headers = response.Headers.ToDictionary(_ => _.Key, _ => _.Value),
                                Body    = await response.Content.ReadAsStringAsync(),
                            },
                        });
                    }
                }
                else
                {
                    await Clients.Caller.Error(response.StatusCode.ToString(), (int)response.StatusCode);
                }
            }
            catch (Exception ex)
            {
                await Clients.Caller.Error(ex.Message, ex.HResult);
            }
        }
コード例 #2
0
        async Task <ApiCallContext> BuildContextAsync(SignalCall call)
        {
            var apiDescriptor = apiRegistration.ApiCollections.SingleOrDefault(_ => _.Name == call.Method);

            if (apiDescriptor == null)
            {
                throw new Exception($"Could not find descriptor by method \"{call.Method}\"");
            }

            var apiMetadata = new ApiMetadata(
                apiDescriptor,
                apiDescriptor.FilterTypes
                .Select(_ => ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, _))
                .Where(_ => _ is IFilterMetadata)
                .Cast <IFilterMetadata>()
                .Union(apiRegistration.GlobalFilters)
                );

            var user = await serviceProvider.GetRequiredService <IAuthenticationProvider>().GetUserAsync(call.AccessToken);

            return(new ApiCallContext(Context.ConnectionId, apiMetadata, user));
        }
コード例 #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);
                }
            }
        }