/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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)); }
/// <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); }
/// <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")); } }
/// <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); } } }
/// <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)); }
/// <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; }
/// <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); }
/// <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)); }
/// <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); }
/// <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; }
/// <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; }
/// <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())); } }
/// <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; }
/// <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); } }