/// <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)); }
/// <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); }
/// <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)); }
/// <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); }
/// <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()); } }
/// <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); } } }
/// <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)); }
/// <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); } }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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); }
public Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter) { if (parameter.Value is string authStr) { context.RequestMessage.Headers.TryAddWithoutValidation("Authorization", authStr); } return(Task.CompletedTask); }
/// <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; }