/// <summary>
 /// 执行Action
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="arguments">参数值</param>
 /// <returns></returns>
 public async Task <TResult> InvokeAsync(ServiceContext context, object?[] arguments)
 {
     try
     {
         using var httpContext = new HttpContext(context);
         var requestContext = new ApiRequestContext(httpContext, this.ApiAction, arguments);
         return(await this.InvokeAsync(requestContext).ConfigureAwait(false));
     }
     catch (HttpRequestException)
     {
         throw;
     }
     catch (Exception ex)
     {
         throw new HttpRequestException(ex.Message, ex);
     }
 }
Example #2
0
        /// <summary>
        /// 处理请求上下文
        /// </summary>
        /// <returns></returns>
        private static async Task HandleRequestAsync(ApiRequestContext context)
        {
            // 参数验证
            var validateProperty = context.HttpContext.HttpApiOptions.UseParameterPropertyValidate;

            foreach (var parameter in context.ApiAction.Parameters)
            {
                var parameterValue = context.Arguments[parameter.Index];
                DataValidator.ValidateParameter(parameter, parameterValue, validateProperty);
            }

            // action特性请求前执行
            foreach (var attr in context.ApiAction.Attributes)
            {
                await attr.OnRequestAsync(context).ConfigureAwait(false);
            }

            // 参数特性请求前执行
            foreach (var parameter in context.ApiAction.Parameters)
            {
                var ctx = new ApiParameterContext(context, parameter);
                foreach (var attr in parameter.Attributes)
                {
                    await attr.OnRequestAsync(ctx).ConfigureAwait(false);
                }
            }

            // Return特性请求前执行
            foreach (var @return in context.ApiAction.Return.Attributes)
            {
                await @return.OnRequestAsync(context).ConfigureAwait(false);
            }

            // GlobalFilter请求前执行
            foreach (var filter in context.HttpContext.HttpApiOptions.GlobalFilters)
            {
                await filter.OnRequestAsync(context).ConfigureAwait(false);
            }

            // Filter请求前执行
            foreach (var filter in context.ApiAction.FilterAttributes)
            {
                await filter.OnRequestAsync(context).ConfigureAwait(false);
            }
        }
Example #3
0
        /// <summary>
        /// 发送http请求
        /// </summary>
        /// <param name="context"></param>
        /// <exception cref="HttpRequestException"></exception>
        /// <returns></returns>
        public static async Task<ApiResponseContext> SendAsync(ApiRequestContext context)
        {
            var actionCache = await GetCaheAsync(context).ConfigureAwait(false);
            if (actionCache != null && actionCache.Value != null)
            {
                context.HttpContext.ResponseMessage = actionCache.Value;
            }
            else
            {
                var client = context.HttpContext.Client;
                using var tokenLinker = new CancellationTokenLinker(context.CancellationTokens);
                var response = await client.SendAsync(context.HttpContext.RequestMessage, tokenLinker.Token).ConfigureAwait(false);

                context.HttpContext.ResponseMessage = response;
                await SetCacheAsync(context, actionCache?.Key, response).ConfigureAwait(false);
            }
            return new ApiResponseContext(context);
        }
Example #4
0
        /// <summary>
        /// 更新响应到缓存
        /// </summary>
        /// <param name="context"></param>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="response">响应消息</param>
        /// <returns></returns>
        private static async Task SetCacheAsync(ApiRequestContext context, string? cacheKey, HttpResponseMessage? response)
        {
            var attribute = context.ApiAction.CacheAttribute;
            if (attribute == null)
            {
                return;
            }

            if (response == null)
            {
                return;
            }

            if (attribute.GetWritePolicy(context) == CachePolicy.Ignore)
            {
                return;
            }

            if (string.IsNullOrEmpty(cacheKey) == true)
            {
                cacheKey = await attribute.GetCacheKeyAsync(context).ConfigureAwait(false);
            }

            if (cacheKey == null)
            {
                return;
            }

            var provider = context.HttpContext.Services.GetService<IResponseCacheProvider>();
            if (provider == null)
            {
                return;
            }

            var cacheEntry = await ResponseCacheEntry.FromResponseMessageAsync(response).ConfigureAwait(false);
            await provider.SetAsync(cacheKey, cacheEntry, attribute.Expiration).ConfigureAwait(false);
        }
Example #5
0
 /// <summary>
 /// Api参数上下文
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameterIndex">参数索引</param>
 public ApiParameterContext(ApiRequestContext context, int parameterIndex)
     : base(context.HttpContext, context.ApiAction, context.Arguments, context.Properties)
 {
     this.index = parameterIndex;
 }
        /// <summary>
        /// 执行Api方法
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task <TResult> InvokeAsync(ApiRequestContext context)
        {
#nullable disable
 /// <summary>
 /// 尝试根据参数名获取参数值
 /// </summary>
 /// <param name="context"></param>
 /// <param name="parameterName">参数名</param>
 /// <param name="value">值</param>
 /// <returns></returns>
 public static bool TryGetArgument(this ApiRequestContext context, string parameterName, out object?value)
 {
     return(context.TryGetArgument(parameterName, StringComparer.Ordinal, out value));
 }
 /// <summary>
 /// 尝试根据参数名获取参数值
 /// </summary>
 /// <typeparam name="TValue"></typeparam>
 /// <param name="context"></param>
 /// <param name="parameterName">参数名</param>
 /// <param name="value">值</param>
 /// <returns></returns>
 public static bool TryGetArgument <TValue>(this ApiRequestContext context, string parameterName, [MaybeNullWhen(false)] out TValue value)
 {
     return(context.TryGetArgument(parameterName, StringComparer.Ordinal, out value));
 }
 /// <summary>
 /// Api参数上下文
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">参数描述</param>
 public ApiParameterContext(ApiRequestContext context, ApiParameterDescriptor parameter)
     : base(context.HttpContext, context.ApiAction, context.Arguments, context.Properties)
 {
     this.Parameter = parameter;
 }
 /// <summary>
 /// Api参数上下文
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameterIndex">参数索引</param>
 public ApiParameterContext(ApiRequestContext context, int parameterIndex)
     : this(context, context.ApiAction.Parameters[parameterIndex])
 {
 }
Example #11
0
 /// <summary>
 /// 执行上下文
 /// </summary>
 /// <param name="request">请求上下文</param>
 /// <returns></returns>
 public static Task <ApiResponseContext> InvokeAsync(ApiRequestContext request)
 {
     return(handler(request));
 }
Example #12
0
 /// <summary>
 /// Api参数上下文
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameterIndex">参数索引</param>
 public ApiParameterContext(ApiRequestContext context, int parameterIndex)
     : base(context.HttpContext, context.ApiAction, context.Arguments, context.UserDatas, context.CancellationTokens)
 {
     this.index = parameterIndex;
 }
Example #13
0
 /// <summary>
 /// Api缓存
 /// </summary>
 /// <param name="context">上下文</param>
 public ApiCache(ApiRequestContext context)
 {
     this.context   = context;
     this.attribute = context.ApiAction.CacheAttribute;
 }