/// <summary>
        /// 获取新的Path与Query
        /// </summary>
        /// <param name="pathQuery">原始path与query</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        private string GetPathQuery(string pathQuery, ApiParameterDescriptor parameter)
        {
            if (parameter.IsSimpleType == true)
            {
                var pName = string.IsNullOrEmpty(this.name) ? parameter.Name : this.name;
                return(this.GetSimplePathQuery(pathQuery, pName, parameter.Value));
            }

            if (parameter.IsDictionaryOfObject == true)
            {
                return(this.GetDictionaryPathQuery <object>(pathQuery, parameter));
            }

            if (parameter.IsDictionaryOfString == true)
            {
                return(this.GetDictionaryPathQuery <string>(pathQuery, parameter));
            }

            if (parameter.IsEnumerable == true)
            {
                return(this.GetEnumerablePathQuery(pathQuery, parameter));
            }

            return(this.GetComplexPathQuery(pathQuery, parameter));
        }
Beispiel #2
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <exception cref="HttpApiConfigException"></exception>
        /// <returns></returns>
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            if (parameter.Value == null)
            {
                throw new ArgumentNullException(parameter.Name);
            }

            if (parameter.Index > 0)
            {
                throw new HttpApiConfigException(this.GetType().Name + "必须修饰于第一个参数");
            }

            var relative = new Uri(parameter.ToString(), UriKind.RelativeOrAbsolute);

            if (relative.IsAbsoluteUri == true)
            {
                context.RequestMessage.RequestUri = relative;
            }
            else
            {
                var baseUri = context.RequestMessage.RequestUri;
                if (baseUri == null)
                {
                    throw new HttpApiConfigException($"请配置{nameof(HttpHostAttribute)}或者Url使用绝对路径");
                }
                context.RequestMessage.RequestUri = new Uri(baseUri, relative);
            }
            return(ApiTask.CompletedTask);
        }
Beispiel #3
0
        /// <summary>
        /// 绑定路由参数到模版
        /// </summary>
        /// <param name="template">路由模版</param>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        private string GetPathQuery(string template, ApiParameterDescriptor parameter)
        {
            var _params = new RouteValueDictionary();

            if (parameter.IsUriParameterType)
            {
                _params.Add(parameter.Name, string.Format(CultureInfo.InvariantCulture, "{0}", parameter.Value));
            }
            else if (parameter.ParameterType.IsArray && parameter.Value is Array array)
            {
                foreach (var item in array)
                {
                    _params.Add(parameter.Name, string.Format(CultureInfo.InvariantCulture, "{0}", item));
                }
            }
            else
            {
                var instance     = parameter.Value;
                var instanceType = parameter.ParameterType;

                var properties = Property.GetProperties(instanceType);
                foreach (var p in properties)
                {
                    var value = instance == null ? null : p.GetValue(instance);
                    _params.Add(p.Name, string.Format(CultureInfo.InvariantCulture, "{0}", value));
                }
            }

            return(BoundTemplate(template, _params));
        }
Beispiel #4
0
        /// <summary>
        /// http请求之前
        /// 值从参数过来
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        Task IApiParameterAttribute.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var headerValue = parameter.Value == null ? null : parameter.Value.ToString();

            this.SetHeaderValue(context, headerValue);
            return(TaskExtend.CompletedTask);
        }
Beispiel #5
0
        /// <summary>
        /// 生成ApiParameterDescriptor
        /// </summary>
        /// <param name="parameter">参数信息</param>
        /// <param name="index">参数索引</param>
        /// <param name="method"></param>
        /// <returns></returns>
        private static ApiParameterDescriptor GetParameterDescriptor(ParameterInfo parameter, int index, MethodInfo method)
        {
            var parameterDescriptor = new ApiParameterDescriptor
            {
                Name               = parameter.Name,
                Index              = index,
                ParameterType      = parameter.ParameterType,
                IsUriParameterType = parameter.ParameterType.IsUriParameterType(),
                Attributes         = parameter.GetCustomAttributes <ApiParameterAttribute>(true).ToArray()
            };

            var methodAttrs = method.GetCustomAttributes <ApiActionAttribute>(true);

            if (methodAttrs.Any(x => x is HttpGetAttribute) && !parameterDescriptor.IsUriParameterType && !parameterDescriptor.ParameterType.IsUriParameterTypeArray())
            {
                throw new Exception($"Get请求方法不支持非Uri支持类型的参数[{parameter.ParameterType}]:{parameter.Name},请在操作方法标记HttpPostAttribute方法特性。");
            }

            if (!parameterDescriptor.Attributes.Any())
            {
                if (methodAttrs.Any(x => x is HttpGetAttribute) || parameterDescriptor.IsUriParameterType || parameterDescriptor.ParameterType.IsUriParameterTypeArray())
                {
                    parameterDescriptor.Attributes = new[] { new PathQueryAttribute() }
                }
                ;
                else
                {
                    parameterDescriptor.Attributes = new[] { new JsonContentAttribute() }
                };
            }

            return(parameterDescriptor);
        }
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 /// <returns></returns>
 void IApiParameterAttribute.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     if (this.WillIgnore(parameter.Value) == false)
     {
         context.RequestMessage.AddFormFieldAsync(parameter.Name, parameter.ToString());
     }
 }
Beispiel #7
0
        /// <summary>
        /// 执行前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">参数信息</param>
        /// <returns></returns>
        public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            switch (this.Kind)
            {
            case Kind.Path:
                await pathQuery.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;

            case Kind.Header:
                await headers.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;

            case Kind.Form:
                await formContent.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;

            case Kind.FormData:
                await formdataContent.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;

            case Kind.JsonBody:
                await jsonContent.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;

            case Kind.XmlBody:
                await xmlContent.BeforeRequestAsync(context, parameter).ConfigureAwait(false);

                break;
            }
        }
        /// <summary>
        /// 获取http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        protected override HttpContent GetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formater = context.HttpApiConfig.JsonFormatter;
            var content  = base.FormatParameter(parameter, formater, this.encoding);

            return(new StringContent(content, this.encoding, "application/json"));
        }
 /// <summary>
 /// 设置参数到http请求内容
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 protected override async Task SetHttpContentAsync(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     var formatter = context.HttpApiConfig.KeyValueFormatter;
     var options   = context.HttpApiConfig.FormatOptions.CloneChange(this.datetimeFormat);
     var keyValues = formatter.Serialize(parameter, options);
     await context.RequestMessage.AddFormFieldAsync(keyValues);
 }
        /// <summary>
        /// 从参数值获取IApiParameterable对象
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private IEnumerable <IApiParameterable> GetApiParameterables(ApiParameterDescriptor parameter)
        {
            if (parameter.Value == null)
            {
                yield break;
            }

            var able = parameter.Value as IApiParameterable;

            if (able != null)
            {
                yield return(able);

                yield break;
            }

            var array = parameter.Value as IEnumerable <IApiParameterable>;

            if (array != null)
            {
                foreach (var ele in array)
                {
                    yield return(ele);
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// 格式化参数为键值对
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        protected IEnumerable <KeyValuePair <string, string> > FormatParameter(ApiParameterDescriptor parameter)
        {
            if (parameter.IsSimpleType == true)
            {
                var kv = this.FormatAsSimple(parameter.Name, parameter.Value);
                return(new[] { kv });
            }

            if (parameter.IsDictionaryOfString == true)
            {
                return(this.FormatAsDictionary <string>(parameter));
            }

            if (parameter.IsDictionaryOfObject == true)
            {
                return(this.FormatAsDictionary <object>(parameter));
            }

            if (parameter.IsEnumerable == true)
            {
                return(this.ForamtAsEnumerable(parameter));
            }

            return(this.FormatAsComplex(parameter));
        }
Beispiel #12
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 /// <returns></returns>
 async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     if (this.WillIgnore(this.stringValue) == false)
     {
         await context.RequestMessage.AddFormFieldAsync(parameter.Name, this.stringValue);
     }
 }
Beispiel #13
0
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.XmlFormatter;
            var xml       = formatter.Serialize(parameter.Value, this.encoding);

            context.RequestMessage.Content = new XmlContent(xml, this.encoding);
        }
        public void NewTest()
        {
            var p1 = typeof(IUserApi).GetMethod("Get2").GetParameters()[0];
            var m1 = new ApiParameterDescriptor(p1);

            Assert.True(m1.Attributes.Count == 1);
            Assert.True(m1.Index == 0);
            Assert.True(m1.Member == p1);
            Assert.True(m1.Name == p1.Name);
            Assert.True(m1.ParameterType == p1.ParameterType);
            Assert.True(m1.ValidationAttributes.Count == 1);
            Assert.True(m1.Value == null);


            var p2 = typeof(IUserApi).GetMethod("Get2").GetParameters()[1];
            var m2 = new ApiParameterDescriptor(p2);

            Assert.True(m2.Attributes.Count == 1);
            Assert.True(m2.Index == 1);
            Assert.True(m2.Member == p2);
            Assert.True(m2.Name == p2.Name);
            Assert.True(m2.ParameterType == p2.ParameterType);
            Assert.True(m2.ValidationAttributes.Count == 0);
            Assert.True(m2.Value == null);
        }
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.KeyValueFormatter;
            var keyValues = formatter.Serialize(parameter);

            context.RequestMessage.AddText(keyValues);
        }
Beispiel #16
0
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.XmlFormatter;
            var content   = formatter.Serialize(parameter.Value, this.encoding);

            context.RequestMessage.Content = new StringContent(content, this.encoding, "application/xml");
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <exception cref="HttpApiConfigException"></exception>
        /// <returns></returns>
        public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var uri = context.RequestMessage.RequestUri;

            if (uri == null)
            {
                throw new HttpApiConfigException($"未配置HttpHost,无法使用参数{parameter.Name}");
            }

            if (this.IsIgnoreWith(parameter) == true)
            {
                return;
            }

            var options = context
                          .HttpApiConfig
                          .FormatOptions
                          .CloneChange(this.DateTimeFormat);

            var keyValues = context
                            .HttpApiConfig
                            .KeyValueFormatter
                            .Serialize(parameter, options)
                            .FormateAs(this.CollectionFormat);

            context.RequestMessage.RequestUri = this.UsePathQuery(uri, keyValues);
            await ApiTask.CompletedTask;
        }
Beispiel #18
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var cancellation = new CancellationTokenSource(this.TimeSpan);

            context.CancellationTokens.Add(cancellation.Token);
            return(ApiTask.CompletedTask);
        }
        /// <summary>
        /// 替换带有花括号的参数的值
        /// </summary>
        /// <param name="uri">Uri</param>
        /// <param name="parameter">参数</param>
        /// <param name="encoding">编码格式</param>
        /// <returns>替换成功则返回true</returns>
        protected Uri UsePathQuery(Uri uri, ApiParameterDescriptor parameter, Encoding encoding)
        {
            var replaced = false;

            // 替换Url中的参数
            if (uri.OriginalString.IndexOf('{') > -1)
            {
                string url   = uri.OriginalString;
                var    regex = new Regex($"{{{parameter.Name}}}", RegexOptions.IgnoreCase);
                url = regex.Replace(url, m =>
                {
                    replaced = true;
                    return(parameter.Value?.ToString().UrlEncode(encoding));
                });
                if (url != uri.OriginalString)
                {
                    uri = new Uri(url);
                }
            }

            if (!replaced)
            {
                string url         = uri.OriginalString;
                string queryString = EncodeParameter(parameter, encoding);
                var    concat      = url.IndexOf('?') > -1 ? "&" : "?";
                var    relativeUri = $"{url}{concat}{queryString}{uri.Fragment}";
                uri = new Uri(uri, relativeUri);
            }

            return(uri);
        }
Beispiel #20
0
        /// <summary>
        /// 生成http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        protected override HttpContent GenerateHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var keyValues   = base.FormatParameter(parameter);
            var httpContent = context.RequestMessage.Content.CastOrCreateMultipartContent();

            httpContent.AddText(keyValues);
            return(httpContent);
        }
Beispiel #21
0
 /// <summary>
 /// 序列化参数为键值对
 /// </summary>
 /// <param name="parameter">参数</param>
 /// <param name="options">选项</param>
 /// <exception cref="ArgumentNullException"></exception>
 /// <returns></returns>
 public IEnumerable <KeyValuePair <string, string> > Serialize(ApiParameterDescriptor parameter, FormatOptions options)
 {
     if (parameter == null)
     {
         throw new ArgumentNullException(nameof(parameter));
     }
     return(this.Serialize(parameter.Name, parameter.Value, options));
 }
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.JsonFormatter;
            var options   = context.HttpApiConfig.FormatOptions.CloneChange(this.datetimeFormat);
            var content   = formatter.Serialize(parameter.Value, options);

            context.RequestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json");
        }
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.JsonFormatter;
            var options   = context.HttpApiConfig.FormatOptions.CloneChange(this.DateTimeFormat);
            var json      = formatter.Serialize(parameter.Value, options);

            context.RequestMessage.Content = new JsonContent(json, Encoding.UTF8);
        }
        /// <summary>
        /// 生成http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        protected override HttpContent GenerateHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var stringValue = parameter.Value == null ? null : parameter.Value.ToString();
            var httpContent = context.RequestMessage.Content.CastOrCreateMultipartContent();

            httpContent.AddText(parameter.Name, stringValue);
            return(httpContent);
        }
Beispiel #25
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 /// <returns></returns>
 async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     if (this.WillIgnore(this.stringValue) == false)
     {
         context.RequestMessage.AddMulitpartText(parameter.Name, this.stringValue);
         await ApiTask.CompletedTask;
     }
 }
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        protected override void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var formatter = context.HttpApiConfig.KeyValueFormatter;
            var options   = context.HttpApiConfig.FormatOptions.CloneChange(this.datetimeFormate);
            var keyValues = formatter.Serialize(parameter, options);

            context.RequestMessage.AddMulitpartText(keyValues);
        }
        /// <summary>
        /// 设置参数到http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <exception cref="HttpApiConfigException"></exception>
        /// <returns></returns>
        protected override async Task SetHttpContentAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var form        = parameter.ToString();
            var httpContent = await UrlEncodedContent.FromHttpContentAsync(context.RequestMessage.Content).ConfigureAwait(false);

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

            context.RequestMessage.Content = httpContent;
        }
Beispiel #28
0
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            const string headerName = "Authorization";
            var          header     = context.RequestMessage.Headers;

            header.Remove(headerName);
            header.TryAddWithoutValidation(headerName, this.GetAuthorizationValue());
            return(ApiTask.CompletedTask);
        }
Beispiel #29
0
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            if (parameter.Value is string authStr)
            {
                context.RequestMessage.Headers.TryAddWithoutValidation("Authorization", authStr);
            }

            return(Task.CompletedTask);
        }
Beispiel #30
0
 /// <summary>
 /// 设置参数到http请求内容
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 /// <exception cref="HttpApiConfigException"></exception>
 protected virtual void SetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     if (context.RequestMessage.Content != null)
     {
         var message = string.Format("参数{0} {1}必须置前", parameter.ParameterType.Name, parameter.Name);
         throw new HttpApiConfigException(message);
     }
     context.RequestMessage.Content = parameter.Value as HttpContent;
 }