예제 #1
0
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        protected override async Task SetHttpContentAsync(ApiParameterContext context)
        {
            var form        = context.ParameterValue?.ToString();
            var fromContent = await FormContent.FromHttpContentAsync(context.HttpContext.RequestMessage.Content).ConfigureAwait(false);

            await fromContent.AddRawFormAsync(form).ConfigureAwait(false);

            context.HttpContext.RequestMessage.Content = fromContent;
        }
예제 #2
0
        /// <summary>
        /// http请求之前
        /// 值从参数过来
        /// </summary>
        /// <param name="context">上下文</param>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            var headerValue = context.ParameterValue?.ToString();

            if (string.IsNullOrEmpty(headerValue) == false)
            {
                context.HttpContext.RequestMessage.Headers.TryAddWithoutValidation(this.name, headerValue);
            }
            return(Task.CompletedTask);
        }
        /// <summary>
        /// 执行前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <returns></returns>
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            var json       = context.SerializeToJson();
            var fieldName  = context.ParameterName;
            var fieldValue = Encoding.UTF8.GetString(json);

            context.HttpContext.RequestMessage.AddFormDataText(fieldName, fieldValue);

            return(Task.CompletedTask);
        }
예제 #4
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="HttpApiInvalidOperationException"></exception>
        /// <returns></returns>
        public sealed override async Task OnRequestAsync(ApiParameterContext context)
        {
            var method = context.HttpContext.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                var message = Resx.unsupported_SetContent.Format(method);
                throw new HttpApiInvalidOperationException(message);
            }
            await this.SetHttpContentAsync(context).ConfigureAwait(false);
        }
예제 #5
0
        /// <summary>
        /// 请求前
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            var parameters = context.Properties.Get <JsonRpcParameters>(typeof(JsonRpcParameters));

            if (parameters == null)
            {
                throw new ApiInvalidConfigException($"请为接口方法{context.ApiAction.Name}修饰{nameof(JsonRpcMethodAttribute)}");
            }

            parameters.Add(context);
            return(Task.CompletedTask);
        }
예제 #6
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public sealed override async Task OnRequestAsync(ApiParameterContext context)
        {
            var method = context.HttpContext.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                var logger = context.GetLogger();
                logger?.LogWarning(Resx.gethead_Content_Warning.Format(method));
            }

            await this.SetHttpContentAsync(context).ConfigureAwait(false);
        }
예제 #7
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            var timeout = context.ParameterValue;

            if (timeout != null)
            {
                var timespan = ConvertToTimeSpan(timeout);
                SetTimeout(context, timespan);
            }

            return(Task.CompletedTask);
        }
예제 #8
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <exception cref="ApiInvalidConfigException"></exception>
 /// <returns></returns>
 public override Task OnRequestAsync(ApiParameterContext context)
 {
     foreach (var item in context.SerializeToKeyValues())
     {
         if (string.IsNullOrEmpty(item.Value) == false)
         {
             var name = this.UnderlineToMinus ? item.Key.Replace("_", "-") : item.Key;
             context.HttpContext.RequestMessage.Headers.TryAddWithoutValidation(name, item.Value);
         }
     }
     return(Task.CompletedTask);
 }
예제 #9
0
        public async Task OnRequestAsync_Parameter()
        {
            var apiAction        = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context          = new TestRequestContext(apiAction, "laojiu");
            var parameterContext = new ApiParameterContext(context, 0);

            var attr = new HeaderAttribute("MyHeader");
            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            context.HttpContext.RequestMessage.Headers.TryGetValues("MyHeader", out IEnumerable <string> values);
            Assert.Equal("laojiu", values.First());
        }
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            if (context.HttpContext.RequestMessage.Method != HttpMethod.Patch)
            {
                throw new ApiInvalidConfigException(Resx.required_PatchMethod);
            }

            var options = context.HttpContext.HttpApiOptions.JsonSerializeOptions;

            context.HttpContext.RequestMessage.Content = new JsonPatchContent(this.oprations, options);

            return(Task.CompletedTask);
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            var uri = context.HttpContext.RequestMessage.RequestUri;

            if (uri == null)
            {
                throw new ApiInvalidConfigException(Resx.required_HttpHost);
            }

            var keyValues = this.SerializeToKeyValues(context).CollectAs(this.CollectionFormat);

            context.HttpContext.RequestMessage.RequestUri = this.CreateUri(uri, keyValues);
            return(Task.CompletedTask);
        }
예제 #12
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public override async Task OnRequestAsync(ApiParameterContext context)
 {
     if (context.ParameterValue is FileInfo fileInfo)
     {
         await AddFileAsync(context, fileInfo).ConfigureAwait(false);
     }
     else if (context.ParameterValue is IEnumerable <FileInfo> fileInfos)
     {
         foreach (var file in fileInfos)
         {
             await AddFileAsync(context, file).ConfigureAwait(false);
         }
     }
 }
예제 #13
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public override async Task OnRequestAsync(ApiParameterContext context)
 {
     if (context.ParameterValue is IApiParameter parameter)
     {
         await parameter.OnRequestAsync(context).ConfigureAwait(false);
     }
     else if (context.ParameterValue is IEnumerable <IApiParameter> parameters)
     {
         foreach (var item in parameters)
         {
             await item.OnRequestAsync(context).ConfigureAwait(false);
         }
     }
 }
예제 #14
0
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            if (context.HttpContext.RequestMessage.Method != HttpMethod.Patch)
            {
                throw new HttpApiInvalidOperationException(Resx.required_PatchMethod);
            }

            var formatter = context.HttpContext.Services.GetRequiredService <IJsonFormatter>();
            var json      = formatter.Serialize(this.oprations, context.HttpContext.Options.JsonSerializeOptions);

            context.HttpContext.RequestMessage.Content = new JsonPatchContent(json);

            return(Task.CompletedTask);
        }
예제 #15
0
        /// <summary>
        /// 执行前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            var hostValue = context.ParameterValue;

            if (hostValue == null)
            {
                return(Task.CompletedTask);
            }

            var httpHost = ConvertToUri(hostValue);

            context.HttpContext.RequestMessage.ReplaceHttpHost(httpHost);
            return(Task.CompletedTask);
        }
예제 #16
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public override Task OnRequestAsync(ApiParameterContext context)
 {
     if (context.ParameterValue is CancellationToken token)
     {
         context.HttpContext.CancellationTokens.Add(token);
     }
     else if (context.ParameterValue is IEnumerable <CancellationToken> tokens)
     {
         foreach (var item in tokens)
         {
             context.HttpContext.CancellationTokens.Add(item);
         }
     }
     return(Task.CompletedTask);
 }
예제 #17
0
        public async Task OnRequestAsync_Parameter()
        {
            var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, "laojiu");

            context.HttpContext.RequestMessage.Method = HttpMethod.Post;
            var parameterContext = new ApiParameterContext(context, 0);

            var attr = new FormDataTextAttribute();
            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            var body = await context.HttpContext.RequestMessage.Content.ReadAsStringAsync();

            Assert.Contains(get("value", "laojiu"), body);
        }
예제 #18
0
        public async Task OnRequestAsync_Parameter_Double_Test()
        {
            var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, 1);

            var attr             = new TimeoutAttribute();
            var parameterContext = new ApiParameterContext(context, 0);
            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            await Task.Delay(20);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
        public async Task OnRequestAsync_Parameter()
        {
            var apiAction = new DefaultApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, "laojiu");

            context.HttpContext.RequestMessage.Method = HttpMethod.Post;
            var parameterContext = new ApiParameterContext(context, 0);

            var attr = new FormFieldAttribute();
            await attr.OnRequestAsync(parameterContext);

            var body = await context.HttpContext.RequestMessage.Content.ReadAsStringAsync();

            Assert.Equal("value=laojiu", body);
        }
예제 #20
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            var keyValues = context.SerializeToKeyValues();

            foreach (var kv in keyValues)
            {
                var value = kv.Value;
                if (value != null)
                {
                    var name = this.UnderlineToMinus ? kv.Key.Replace("_", "-") : kv.Key;
                    context.HttpContext.RequestMessage.Headers.TryAddWithoutValidation(name, value);
                }
            }
            return(Task.CompletedTask);
        }
        /// <summary>
        /// 处理请求上下文
        /// </summary>
        /// <returns></returns>
        private static async Task HandleRequestAsync(ApiRequestContext context)
        {
            // 参数验证
            var validateProperty = context.HttpContext.HttpApiOptions.UseParameterPropertyValidate;

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

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

            // 参数特性请求前执行
            foreach (var parameter in context.ActionDescriptor.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.ActionDescriptor.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.ActionDescriptor.FilterAttributes)
            {
                await filter.OnRequestAsync(context).ConfigureAwait(false);
            }
        }
예제 #22
0
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            if (context.HttpContext.RequestMessage.Method != HttpMethod.Patch)
            {
                throw new ApiInvalidConfigException(Resx.required_PatchMethod);
            }

            var jsonPatchContent = new JsonPatchContent();

            context.HttpContext.RequestMessage.Content = jsonPatchContent;

            var options    = context.HttpContext.Options.JsonSerializeOptions;
            var serializer = context.HttpContext.Services.GetRequiredService <IJsonSerializer>();

            serializer.Serialize(jsonPatchContent, this.oprations, options);

            return(Task.CompletedTask);
        }
예제 #23
0
        public Task OnRequestAsync(ApiParameterContext context)
        {
            string parameterName = _aliasName;

            if (string.IsNullOrEmpty(parameterName))
            {
                parameterName = context.ParameterName;
            }

            string text = context.ParameterValue?.ToString();

            if (!string.IsNullOrEmpty(text))
            {
                AddByAppendType(context.HttpContext.RequestMessage.Headers, parameterName, text);
            }

            return(Task.CompletedTask);
        }
예제 #24
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public sealed override async Task OnRequestAsync(ApiParameterContext context)
        {
            var method = context.HttpContext.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                var loggerFactory = context.HttpContext.ServiceProvider.GetService <ILoggerFactory>();
                if (loggerFactory != null)
                {
                    var action       = context.ApiAction.Member;
                    var categoryName = $"{action.DeclaringType?.Namespace}.{action.DeclaringType?.Name}.{action.Name}";
                    var logger       = loggerFactory.CreateLogger(categoryName);
                    logger.LogWarning(Resx.gethead_Content_Warning.Format(method));
                }
            }

            await this.SetHttpContentAsync(context).ConfigureAwait(false);
        }
예제 #25
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            if (context.Parameter.Index > 0)
            {
                throw new ApiInvalidConfigException(Resx.invalid_UriAttribute);
            }

            var uriValue = context.ParameterValue;

            if (uriValue == null)
            {
                throw new ArgumentNullException(context.ParameterName);
            }

            var uri     = ConvertToUri(uriValue);
            var request = context.HttpContext.RequestMessage;

            request.RequestUri = request.MakeRequestUri(uri);

            return(Task.CompletedTask);
        }
예제 #26
0
        public override Task OnRequestAsync(ApiParameterContext context)
        {
            var org = context.ParameterValue?.ToString();

            if (string.IsNullOrEmpty(org) == true)
            {
                org = context
                      .HttpContext
                      .ServiceProvider
                      .GetRequiredService <IOptionsMonitor <InfuxdbOptions> >()
                      .CurrentValue
                      .DefaultOrg;
            }

            if (string.IsNullOrEmpty(org) == true)
            {
                throw new ArgumentNullException(context.ParameterName, $"org不能为空,除非配置了{nameof(InfuxdbOptions.DefaultOrg)}");
            }

            context.HttpContext.RequestMessage.AddUrlQuery(context.ParameterName, org);
            return(Task.CompletedTask);
        }
예제 #27
0
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <returns></returns>
        protected override Task SetHttpContentAsync(ApiParameterContext context)
        {
            if (context.HttpContext.RequestMessage.Content != null)
            {
                var message = Resx.parameter_MustPutForward.Format(context.Parameter.Member);
                throw new ApiInvalidConfigException(message);
            }

            if (context.ParameterValue != null)
            {
                if (context.ParameterValue is HttpContent httpContent)
                {
                    context.HttpContext.RequestMessage.Content = httpContent;
                }
                else
                {
                    var message = Resx.parameter_MustbeHttpContenType.Format(context.Parameter.Member);
                    throw new ApiInvalidConfigException(message);
                }
            }

            return(Task.CompletedTask);
        }
예제 #28
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <exception cref="ApiInvalidConfigException"></exception>
        /// <returns></returns>
        public Task OnRequestAsync(ApiParameterContext context)
        {
            if (context.ParameterValue == null)
            {
                return(Task.CompletedTask);
            }

            if (context.ParameterValue is TimeSpan timespan)
            {
                this.SetTimeout(context, timespan);
            }
            else if (context.ParameterValue is IConvertible convertible)
            {
                var milliseconds = convertible.ToDouble(null);
                var timeout      = System.TimeSpan.FromMilliseconds(milliseconds);
                this.SetTimeout(context, timeout);
            }
            else
            {
                throw new ApiInvalidConfigException(Resx.parameter_CannotCvtTimeout.Format(context.Parameter.Member));
            }

            return(Task.CompletedTask);
        }
예제 #29
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public Task OnRequestAsync(ApiParameterContext context)
 {
     context.HttpContext.RequestMessage.AddFormDataText(context.ParameterName, context.ParameterValue?.ToString());
     return(Task.CompletedTask);
 }
    private ApiDescription CreateApiDescription(
        ControllerActionDescriptor action,
        string?httpMethod,
        string?groupName)
    {
        var parsedTemplate = ParseTemplate(action);

        var apiDescription = new ApiDescription()
        {
            ActionDescriptor = action,
            GroupName        = groupName,
            HttpMethod       = httpMethod,
            RelativePath     = GetRelativePath(parsedTemplate),
        };

        var templateParameters = parsedTemplate?.Parameters?.ToList() ?? new List <TemplatePart>();

        var parameterContext = new ApiParameterContext(_modelMetadataProvider, action, templateParameters);

        foreach (var parameter in GetParameters(parameterContext))
        {
            apiDescription.ParameterDescriptions.Add(parameter);
        }

        var requestMetadataAttributes = GetRequestMetadataAttributes(action);

        var apiResponseTypes = _responseTypeProvider.GetApiResponseTypes(action);

        foreach (var apiResponseType in apiResponseTypes)
        {
            apiDescription.SupportedResponseTypes.Add(apiResponseType);
        }

        // It would be possible here to configure an action with multiple body parameters, in which case you
        // could end up with duplicate data.
        if (apiDescription.ParameterDescriptions.Count > 0)
        {
            var contentTypes = GetDeclaredContentTypes(requestMetadataAttributes);
            foreach (var parameter in apiDescription.ParameterDescriptions)
            {
                if (parameter.Source == BindingSource.Body)
                {
                    // For request body bound parameters, determine the content types supported
                    // by input formatters.
                    var requestFormats = GetSupportedFormats(contentTypes, parameter.Type);
                    foreach (var format in requestFormats)
                    {
                        apiDescription.SupportedRequestFormats.Add(format);
                    }
                }
                else if (parameter.Source == BindingSource.FormFile)
                {
                    // Add all declared media types since FormFiles do not get processed by formatters.
                    foreach (var contentType in contentTypes)
                    {
                        apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat
                        {
                            MediaType = contentType,
                        });
                    }
                }
            }
        }

        return(apiDescription);
    }