private static Dictionary<string, RouteParameter> GetRouteParameters(ServiceMethodMetadata metadata) { var parameters = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (Match match in parameterNamePattern.Matches(metadata.UrlInfo.UrlTemplate)) { parameters.Add(match.Result("$1")); } var routeParameters = new Dictionary<string, RouteParameter>(StringComparer.OrdinalIgnoreCase); foreach (ParameterInfo methodParameter in metadata.MethodInfo.GetParameters()) { if (!parameters.Contains(methodParameter.Name)) { continue; } var constraintAttribute = methodParameter.GetCustomAttribute<ConstraintAttribute>(false); if (constraintAttribute != null) { routeParameters.Add(methodParameter.Name, new RouteParameter(methodParameter.Name.ToLowerInvariant(), constraintAttribute.PatternRegex)); } else { routeParameters.Add(methodParameter.Name, new RouteParameter(methodParameter.Name.ToLowerInvariant(), null)); } } return routeParameters; }
private static string GetUrlTemplate(ServiceMethodMetadata metadata, IProxyMetadata proxyMetadata) { string urlTemplate = (metadata.ServiceUrl + (metadata.UrlInfo.UrlTemplate.Length > 0 ? UrlSeparator + metadata.UrlInfo.UrlTemplate.TrimStart(UrlSeparator[0]) : UrlSeparator)).Trim(UrlSeparator[0]); if (proxyMetadata == null) { return urlTemplate; } var parameters = GetQueryStringParameters(metadata, proxyMetadata).Where(p => p.ExampleValue != null); var parameterBuilder = new StringBuilder(); foreach (var parameter in parameters) { if (parameterBuilder.Length > 0) { parameterBuilder.Append("&"); } parameterBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}={{{0}}}", HttpUtility.UrlEncode(parameter.Name)); } if (parameterBuilder.Length == 0) { return urlTemplate; } return urlTemplate + "?" + parameterBuilder; }
public ServiceRouteConstraint(ServiceMethodMetadata metadata) { m_httpMethods = new HashSet<HttpMethod>(metadata.UrlInfo.HttpMethods); m_parameters = GetRouteParameters(metadata); }
private static bool HasResource(ServiceMethodMetadata metadata, HttpMethod httpMethod) { if (httpMethod != HttpMethod.Post && httpMethod != HttpMethod.Put && httpMethod != HttpMethod.Patch) { return false; } var methodParameters = metadata.MethodInfo.GetParameters(); if (methodParameters.Any(p => String.Equals("resource", p.Name, StringComparison.OrdinalIgnoreCase))) { return true; } return methodParameters.Any(p => Attribute.IsDefined(p, typeof(ResourceAttribute), false)); }
private static ProxyOperation GenerateProxyOperation(ServiceMethodMetadata metadata) { if (metadata.MethodInfo.DeclaringType == null) { return null; } IProxyMetadata proxyMetadata = ServiceContractTypeRegistry.GetProxyMetadata(metadata.MethodInfo.DeclaringType); if (proxyMetadata != null && proxyMetadata.IsHidden(metadata.MethodInfo)) { return null; } IReadOnlyList<XmlDocMetadata> contractDocumentation; XmlDocMetadata methodDocumentation = null; var xmlDocFactory = Rest.Configuration.Options.XmlDocFactory; if (xmlDocFactory != null && xmlDocFactory.Value.TryGetValue(metadata.MethodInfo.DeclaringType, out contractDocumentation)) { methodDocumentation = contractDocumentation.FirstOrDefault(x => x.Method == metadata.MethodInfo); } var operation = new ProxyOperation { ServiceUrl = metadata.ServiceUrl, UrlTempate = GetUrlTemplate(metadata, proxyMetadata), HttpMethod = metadata.UrlInfo.HttpMethods.First(), SupportedHttpMethods = GetSupportedHttpMethods(metadata), MetadataUrl = String.Concat("metadata?oid=", metadata.ServiceMethodId), ProxyUrl = String.Concat("proxy?oid=", metadata.ServiceMethodId), Description = GetDescription(metadata.MethodInfo, proxyMetadata, methodDocumentation), LongDescription = GetLongDescription(metadata.MethodInfo, proxyMetadata, methodDocumentation), ResultType = metadata.MethodInfo.ReturnType, RouteParameters = GetParameters(metadata, proxyMetadata), HttpsPort = proxyMetadata != null && proxyMetadata.GetHttps(metadata.MethodInfo) != null ? proxyMetadata.GetHttps(metadata.MethodInfo).Port : 0, IsIPFiltered = proxyMetadata != null && proxyMetadata.IsIPFiltered(metadata.MethodInfo), DoesNotSupportJson = proxyMetadata != null && !proxyMetadata.HasJsonSupport(metadata.MethodInfo), DoesNotSupportXml = proxyMetadata != null && !proxyMetadata.HasXmlSupport(metadata.MethodInfo), Credentials = GetCredentials(metadata, proxyMetadata), AdditionalHeaders = proxyMetadata != null ? proxyMetadata.GetHeaders(metadata.MethodInfo) : new List<HeaderMetadata>() }; operation.StatusCodes = GetStatusCodes(metadata.MethodInfo, proxyMetadata, operation.HasResource, operation.HasResponse, operation.HttpsPort > 0); operation.HasResource = HasResource(metadata, operation.HttpMethod); Tuple<ResourceExampleMetadata, ResourceExampleMetadata> resourceExampleTypes = GetResourceExampleTypes(metadata.MethodInfo, proxyMetadata); operation.RequestResourceExample = resourceExampleTypes.Item1; operation.ResponseResourceExample = resourceExampleTypes.Item2; return operation; }
private static AuthenticationMetadata GetCredentials(ServiceMethodMetadata metadata, IProxyMetadata proxyMetadata) { if (proxyMetadata == null) { return null; } AuthenticationMetadata authenticationInfo = proxyMetadata.GetAuthentication(metadata.MethodInfo); if (authenticationInfo == null) { return null; } if (!String.IsNullOrEmpty(authenticationInfo.RelativeUrlToMatch) && !authenticationInfo.RelativeUrlToMatch.Trim().TrimStart('~', '/').Equals(metadata.ServiceUrl, StringComparison.OrdinalIgnoreCase)) { return null; } return authenticationInfo; }
private static IEnumerable<ParameterMetadata> GetRouteParameters(ServiceMethodMetadata metadata, IProxyMetadata proxyMetadata) { var routeParameters = new List<ParameterMetadata>(); foreach (ParameterInfo parameter in metadata.MethodInfo.GetParameters()) { if (metadata.UrlInfo.UrlTemplate.IndexOf(String.Concat("{", parameter.Name, "}"), StringComparison.OrdinalIgnoreCase) < 0) { continue; } ParameterMetadata parameterMetadata = proxyMetadata != null ? proxyMetadata.GetParameter(metadata.MethodInfo, parameter.Name, RequestParameterType.Route) : null; var routeParameter = new ParameterMetadata { Name = parameter.Name.ToLowerInvariant(), ParameterType = RequestParameterType.Route, Type = parameter.ParameterType, IsOptionalParameter = parameter.DefaultValue != DBNull.Value, RegexConstraint = GetParameterConstraint(parameter), ExampleValue = parameterMetadata != null ? parameterMetadata.ExampleValue : null, AllowedValues = parameterMetadata != null ? parameterMetadata.AllowedValues : null }; routeParameters.Add(routeParameter); } return routeParameters; }
private static IEnumerable<ParameterMetadata> GetBodyParameters(ServiceMethodMetadata metadata, IProxyMetadata proxyMetadata) { var parameters = new List<ParameterMetadata>(); if (proxyMetadata == null) { return parameters; } foreach (var parameter in proxyMetadata.GetParameters(metadata.MethodInfo, RequestParameterType.Body)) { parameters.Add(new ParameterMetadata { Name = parameter.Name.ToLowerInvariant(), ParameterType = parameter.ParameterType, Type = parameter.Type, IsOptionalParameter = parameter.IsOptionalParameter, RegexConstraint = parameter.RegexConstraint, ExampleValue = parameter.ExampleValue, AllowedValues = parameter.AllowedValues }); } var bodyParameters = metadata.MethodInfo.GetParameters() .Where(x => Attribute.IsDefined(x, typeof(FromBodyAttribute)) && parameters.All(p => p.Name != x.Name.ToLowerInvariant())) .ToArray(); foreach (ParameterInfo bodyParameter in bodyParameters) { parameters.Add(new ParameterMetadata { Name = bodyParameter.Name.ToLowerInvariant(), ParameterType = RequestParameterType.Body, Type = bodyParameter.ParameterType }); } return parameters; }
private static ICollection<ParameterMetadata> GetParameters(ServiceMethodMetadata metadata, IProxyMetadata proxyMetadata) { var parameters = new List<ParameterMetadata>(GetQueryStringParameters(metadata, proxyMetadata)); parameters.AddRange(GetBodyParameters(metadata, proxyMetadata)); parameters.AddRange(GetRouteParameters(metadata, proxyMetadata)); IReadOnlyList<XmlDocMetadata> contractDocumentation; XmlDocMetadata methodDocumentation = null; var xmlDocFactory = Rest.Configuration.Options.XmlDocFactory; if (xmlDocFactory != null && metadata.MethodInfo.DeclaringType != null && xmlDocFactory.Value.TryGetValue(metadata.MethodInfo.DeclaringType, out contractDocumentation)) { methodDocumentation = contractDocumentation.FirstOrDefault(x => x.Method == metadata.MethodInfo); } if (methodDocumentation != null) { foreach (ParameterMetadata parameter in parameters) { string description; if (methodDocumentation.Parameters.TryGetValue(parameter.Name, out description)) { parameter.Description = description; } } } return parameters.Distinct().ToList(); }
private static string GetSupportedHttpMethods(ServiceMethodMetadata metadata) { return String.Join(", ", metadata.UrlInfo.HttpMethods.Where(m => m != metadata.UrlInfo.HttpMethods.First()).Select(m => m.ToString().ToUpperInvariant())); }