/// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var token = (CancellationToken)parameter.Value;

            context.CancellationTokens.Add(token);
            return(ApiTask.CompletedTask);
        }
Beispiel #2
0
        /// <summary>
        /// 生成ApiParameterDescriptor
        /// </summary>
        /// <param name="parameter">参数信息</param>
        /// <returns></returns>
        private static ApiParameterDescriptor GetParameterDescriptor(ParameterInfo parameter)
        {
            var parameterType = parameter.ParameterType;
            var descriptor    = new ApiParameterDescriptor
            {
                Value                = null,
                Name                 = parameter.Name,
                Index                = parameter.Position,
                ParameterType        = parameterType,
                IsApiParameterable   = parameterType.IsInheritFrom <IApiParameterable>() || parameterType.IsInheritFrom <IEnumerable <IApiParameterable> >(),
                IsHttpContent        = parameterType.IsInheritFrom <HttpContent>(),
                IsSimpleType         = parameterType.IsSimple(),
                IsEnumerable         = parameterType.IsInheritFrom <IEnumerable>(),
                IsDictionaryOfObject = parameterType.IsInheritFrom <IDictionary <string, object> >(),
                IsDictionaryOfString = parameterType.IsInheritFrom <IDictionary <string, string> >(),
                Attributes           = parameter.GetAttributes <IApiParameterAttribute>(true).ToArray()
            };

            if (descriptor.Attributes.Length == 0)
            {
                if (descriptor.IsApiParameterable == true)
                {
                    descriptor.Attributes = new[] { new ParameterableAttribute() };
                }
                else if (descriptor.IsHttpContent == true)
                {
                    descriptor.Attributes = new[] { new HttpContentAttribute() };
                }
                else
                {
                    descriptor.Attributes = new[] { new PathQueryAttribute() };
                }
            }
            return(descriptor);
        }
Beispiel #3
0
        /// <summary>
        /// 将参数值序列化为键值对
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        public IEnumerable <KeyValuePair <string, string> > Serialize(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));
        }
        /// <summary>
        /// 获取http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        protected override HttpContent GetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var encoding = Encoding.UTF8;
            var body     = this.GetFormContent(parameter, encoding);

            return(new StringContent(body, encoding, "application/x-www-form-urlencoded"));
        }
        /// <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);
                }
            }
        }
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var httpContent = context.EnsureNoGet().RequestMessage.Content.CastOrCreateMultipartContent();

            httpContent.AddFile(this.GetStream(), parameter.Name, this.FileName, this.ContentType);
            context.RequestMessage.Content = httpContent;
            await TaskExtend.CompletedTask;
        }
Beispiel #7
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var ables = this.GetApiParameterables(parameter);

            foreach (var item in ables)
            {
                await item?.BeforeRequestAsync(context, parameter);
            }
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var keyValue    = new KeyValuePair <string, string>(parameter.Name, this.stringValue);
            var httpContent = await context.EnsureNoGet().RequestMessage.Content.MergeKeyValuesAsync(new[] { keyValue });

            context.RequestMessage.Content = httpContent;

            await TaskExtend.CompletedTask;
        }
Beispiel #9
0
        /// <summary>
        /// 将参数值序列化为json文本
        /// </summary>
        /// <param name="parameter">对象</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        public string Serialize(ApiParameterDescriptor parameter, Encoding encoding)
        {
            if (parameter.Value == null)
            {
                return(null);
            }
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

            return(serializer.Serialize(parameter.Value));
        }
Beispiel #10
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var header = context.RequestMessage.Headers;

            header.Remove(scheme);
            if (this.authValue != null)
            {
                header.TryAddWithoutValidation(scheme, this.authValue);
            }
            return(ApiTask.CompletedTask);
        }
Beispiel #11
0
        /// <summary>
        /// 获取http请求内容
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        protected override HttpContent GetHttpContent(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var xmlSerializer = new XmlSerializer(parameter.ParameterType);

            using (var stream = new MemoryStream())
            {
                xmlSerializer.Serialize(stream, parameter.Value);
                var xml = Encoding.UTF8.GetString(stream.ToArray());
                return(new StringContent(xml, Encoding.UTF8, "application/xml"));
            }
        }
Beispiel #12
0
        /// <summary>
        /// 数组为键值对
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        private IEnumerable <KeyValuePair <string, string> > ForamtAsEnumerable(ApiParameterDescriptor parameter)
        {
            var array = parameter.Value as IEnumerable;

            if (array == null)
            {
                return(Enumerable.Empty <KeyValuePair <string, string> >());
            }

            return(from item in array.Cast <object>()
                   select this.FormatAsSimple(parameter.Name, item));
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public void BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var ables = this.GetApiParameterables(parameter);

            foreach (var item in ables)
            {
                if (item != null)
                {
                    item.BeforeRequestAsync(context, parameter);
                }
            }
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var ables = this.GetApiParameterables(parameter);

            foreach (var item in ables)
            {
                if (item != null)
                {
                    await item.BeforeRequestAsync(context, parameter).ConfigureAwait(false);
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// 生成数组的表单内容
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        private string GetContentArray(ApiParameterDescriptor parameter, Encoding encoding)
        {
            var array = parameter.Value as Array;

            if (array == null)
            {
                return(null);
            }

            var keyValues = array.Cast <object>().Select(item => this.GetContentSimple(parameter.Name, item, encoding));

            return(string.Join("&", keyValues));
        }
Beispiel #16
0
        /// <summary>
        /// 生成表单内容
        /// key1=value1&key2=value2
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        protected virtual string GetFormContent(ApiParameterDescriptor parameter, Encoding encoding)
        {
            if (parameter.IsSimpleType == true)
            {
                return(this.GetContentSimple(parameter.Name, parameter.Value, encoding));
            }
            else if (parameter.ParameterType.IsArray == true)
            {
                return(this.GetContentArray(parameter, encoding));
            }

            return(this.GetContentComplex(parameter, encoding));
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public override async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            if (this.IgnoreWhenNull && parameter.Value == null)
            {
                return;
            }

            var uri       = context.RequestMessage.RequestUri;
            var pathQuery = this.GetPathQuery(uri.LocalPath + uri.Query, parameter);

            context.RequestMessage.RequestUri = new Uri(uri, pathQuery);
            await TaskEx.CompletedTask;
        }
Beispiel #18
0
        /// <summary>
        /// 生成复杂类型的表单内容
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        private string GetContentComplex(ApiParameterDescriptor parameter, Encoding encoding)
        {
            var instance  = parameter.Value;
            var keyValues = Property
                            .GetProperties(parameter.ParameterType)
                            .Select(p =>
            {
                var value = instance == null ? null : p.GetValue(instance);
                return(this.GetContentSimple(p.Name, value, encoding));
            });

            return(string.Join("&", keyValues));
        }
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var fileInfo = parameter.Value as FileInfo;

            if (fileInfo != null)
            {
                var stream          = fileInfo.Open(FileMode.Open, FileAccess.Read);
                var fileName        = Path.GetFileName(fileInfo.FullName);
                var encodedFileName = HttpUtility.UrlEncode(fileName, Encoding.UTF8);
                context.RequestMessage.AddMulitpartFile(stream, parameter.Name, encodedFileName, null);
            }
            return(ApiTask.CompletedTask);
        }
        /// <summary>
        /// 获取新的Path与Query
        /// </summary>
        /// <param name="pathQuery">原始path与query</param>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        private string GetPathQueryComplex(string pathQuery, ApiParameterDescriptor parameter)
        {
            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);
                pathQuery = this.GetPathQuerySimple(pathQuery, p.Name, value);
            }
            return(pathQuery);
        }
Beispiel #21
0
 /// <summary>
 /// 从参数值获取IApiParameterable对象
 /// </summary>
 /// <param name="parameter"></param>
 /// <returns></returns>
 private IEnumerable <IApiParameterable> GetApiParameterables(ApiParameterDescriptor parameter)
 {
     if (parameter.Value is IApiParameterable able)
     {
         yield return(able);
     }
     else if (parameter.Value is IEnumerable <IApiParameterable> array)
     {
         foreach (var ele in array)
         {
             yield return(ele);
         }
     }
 }
        /// <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)
            {
                return(this.GetPathQuerySimple(pathQuery, parameter.Name, parameter.Value));
            }

            if (parameter.ParameterType.IsArray == true)
            {
                return(this.GetPathQueryArray(pathQuery, parameter));
            }

            return(this.GetPathQueryComplex(pathQuery, parameter));
        }
Beispiel #23
0
 /// <summary>
 /// http请求之前
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="parameter">特性关联的参数</param>
 /// <returns></returns>
 public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
 {
     if (parameter.Value is IApiParameterable able)
     {
         await able.BeforeRequestAsync(context, parameter).ConfigureAwait(false);
     }
     else if (parameter.Value is IEnumerable <IApiParameterable> array)
     {
         foreach (var item in array)
         {
             await item.BeforeRequestAsync(context, parameter).ConfigureAwait(false);
         }
     }
 }
        /// <summary>
        /// 复杂类型为键值对
        /// </summary>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        private IEnumerable <KeyValuePair <string, string> > FormatAsComplex(ApiParameterDescriptor parameter)
        {
            var instance = parameter.Value;

            if (instance == null)
            {
                return(Enumerable.Empty <KeyValuePair <string, string> >());
            }

            return
                (from p in Property.GetProperties(instance.GetType())
                 let value = p.GetValue(instance)
                             select this.FormatAsSimple(p.Name, value));
        }
        /// <summary>
        /// 获取新的Path与Query
        /// </summary>
        /// <param name="pathQuery">原始path与query</param>
        /// <param name="parameter">参数</param>
        /// <returns></returns>
        private string GetPathQueryArray(string pathQuery, ApiParameterDescriptor parameter)
        {
            var array = parameter.Value as Array;

            if (array == null)
            {
                return(pathQuery);
            }

            foreach (var item in array)
            {
                pathQuery = this.GetPathQuerySimple(pathQuery, parameter.Name, item);
            }
            return(pathQuery);
        }
Beispiel #26
0
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的属性</param>
        async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var method = context.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                return;
            }

            var httpContent = context.RequestMessage.Content.CastMultipartContent();
            var fileContent = new MulitpartFileContent(this.GetStream(), parameter.Name, this.FileName, this.ContentType);

            httpContent.Add(fileContent);
            context.RequestMessage.Content = httpContent;
            await TaskExtend.CompletedTask;
        }
Beispiel #27
0
        /// <summary>
        /// 执行请求前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var method = context.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                var message = string.Format("{0}方法不支持使用{1}", method, this.GetType().Name);
                throw new NotSupportedException(message);
            }

            var httpContent = context.RequestMessage.Content.CastOrCreateMultipartContent();

            httpContent.AddFile(this.GetStream(), parameter.Name, this.FileName, this.ContentType);
            context.RequestMessage.Content = httpContent;
            await TaskExtend.CompletedTask;
        }
Beispiel #28
0
        /// <summary>
        /// 将参数值序列化为xml文本
        /// </summary>
        /// <param name="parameter">对象</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        public string Serialize(ApiParameterDescriptor parameter, Encoding encoding)
        {
            if (parameter.Value == null)
            {
                return(null);
            }

            var xmlSerializer = new XmlSerializer(parameter.Value.GetType());

            using (var stream = new MemoryStream())
            {
                var xmlWriter = new XmlTextWriter(stream, encoding);
                xmlSerializer.Serialize(xmlWriter, parameter.Value);
                return(encoding.GetString(stream.ToArray()));
            }
        }
Beispiel #29
0
        /// <summary>
        /// http请求之前
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="parameter">特性关联的参数</param>
        /// <returns></returns>
        async Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
        {
            var method = context.RequestMessage.Method;

            if (method == HttpMethod.Get || method == HttpMethod.Head)
            {
                var message = string.Format("{0}方法不支持使用{1}", method, this.GetType().Name);
                throw new NotSupportedException(message);
            }

            var keyValue    = new KeyValuePair <string, string>(parameter.Name, this.stringValue);
            var httpContent = await context.RequestMessage.Content.MergeKeyValuesAsync(new[] { keyValue });

            context.RequestMessage.Content = httpContent;

            await TaskExtend.CompletedTask;
        }
Beispiel #30
0
        /// <summary>
        /// 验证参数值输入合法性
        /// 验证参数的属性值输入合法性
        /// </summary>
        /// <param name="parameter">参数描述</param>
        /// <param name="validateProperty">是否验证属性值</param>
        /// <exception cref="ValidationException"></exception>
        public static void ValidateParameter(ApiParameterDescriptor parameter, bool validateProperty)
        {
            var name     = parameter.Name;
            var instance = parameter.Value;

            foreach (var validation in parameter.ValidationAttributes)
            {
                validation.Validate(instance, name);
            }

            if (validateProperty == true && IsNeedValidateProperty(instance) == true)
            {
                var ctx = new ValidationContext(instance)
                {
                    MemberName = name
                };
                Validator.ValidateObject(instance, ctx, true);
            }
        }