private bool RunOperationProcessors(SwaggerDocument document, MethodInfo methodInfo, SwaggerOperationDescription operationDescription, List <SwaggerOperationDescription> allOperations, SwaggerGenerator swaggerGenerator) { // 1. Run from settings foreach (var operationProcessor in Settings.OperationProcessors) { if (operationProcessor.Process(new OperationProcessorContext(document, operationDescription, methodInfo, swaggerGenerator, allOperations)) == false) { return(false); } } // 2. Run from class attributes var operationProcessorAttribute = methodInfo.DeclaringType.GetTypeInfo() .GetCustomAttributes() // 3. Run from method attributes .Concat(methodInfo.GetCustomAttributes()) .Where(a => a.GetType().Name == "SwaggerOperationProcessorAttribute"); foreach (dynamic attribute in operationProcessorAttribute) { var operationProcessor = Activator.CreateInstance(attribute.Type); if (operationProcessor.Process(methodInfo, operationDescription, swaggerGenerator, allOperations) == false) { return(false); } } return(true); }
private static string GetPathExpression(SwaggerOperationDescription operation) { string pathExpression = operation.Path; pathExpression = pathExpression.Replace("{namespace}", "{@namespace}"); return(pathExpression); }
private void UpdateConsumedTypes(SwaggerOperationDescription operationDescription) { if (operationDescription.Operation.ActualParameters.Any(p => p.IsBinary)) { operationDescription.Operation.TryAddConsumes("multipart/form-data"); } }
public async Task ProcessAsync_Adds200StatusCodeForVoidResponse() { // Arrange var apiDescription = new ApiDescription { SupportedResponseTypes = { new ApiResponseType { Type = typeof(void), StatusCode = 0, } } }; var operationDescription = new SwaggerOperationDescription { Operation = new SwaggerOperation() }; var context = GetContext(apiDescription); var processor = new OperationResponseProcessor((AspNetCoreToSwaggerGeneratorSettings)context.Settings); // Act await processor.ProcessAsync(context); // Assert Assert.Collection( context.OperationDescription.Operation.Responses, kvp => { Assert.Equal("200", kvp.Key); Assert.Null(kvp.Value.Schema); }); }
private async Task <bool> GenerateForControllerAsync(SwaggerDocument document, Type controllerType, IEnumerable <Tuple <ApiDescription, ControllerActionDescriptor> > controllerApiDescriptionGroup, SwaggerGenerator swaggerGenerator, SwaggerSchemaResolver schemaResolver) { var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (hasIgnoreAttribute) { return(false); } var operations = new List <Tuple <SwaggerOperationDescription, ApiDescription, MethodInfo, IEnumerable <string>, IEnumerable <string> > >(); foreach (var item in controllerApiDescriptionGroup) { var apiDescription = item.Item1; var method = item.Item2.MethodInfo; var actionHasIgnoreAttribute = method.GetCustomAttributes().Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (actionHasIgnoreAttribute) { continue; } var path = apiDescription.RelativePath; if (!path.StartsWith("/", StringComparison.Ordinal)) { path = "/" + path; } var controllerActionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor; var httpMethod = apiDescription.HttpMethod?.ToLowerInvariant() ?? SwaggerOperationMethod.Get; var operationDescription = new SwaggerOperationDescription { Path = path, Method = httpMethod, Operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null, OperationId = GetOperationId(document, controllerActionDescriptor, method) } }; var consumes = apiDescription.SupportedRequestFormats .Select(f => f.MediaType) .Distinct(); var produces = apiDescription.SupportedResponseTypes .SelectMany(t => t.ApiResponseFormats.Select(f => f.MediaType)) .Distinct(); operations.Add(new Tuple <SwaggerOperationDescription, ApiDescription, MethodInfo, IEnumerable <string>, IEnumerable <string> >( operationDescription, apiDescription, method, consumes, produces)); } return(await AddOperationDescriptionsToDocumentAsync(document, controllerType, operations, swaggerGenerator, schemaResolver).ConfigureAwait(false)); }
private void ProcessSwaggerTagsAttribute(SwaggerDocument document, SwaggerOperationDescription operationDescription, MethodInfo methodInfo) { dynamic tagsAttribute = methodInfo .GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "SwaggerTagsAttribute"); if (tagsAttribute != null) { var tags = ((string[])tagsAttribute.Tags).ToList(); foreach (var tag in tags) { if (operationDescription.Operation.Tags.All(t => t != tag)) operationDescription.Operation.Tags.Add(tag); if (ObjectExtensions.HasProperty(tagsAttribute, "AddToDocument") && tagsAttribute.AddToDocument) { if (document.Tags == null) document.Tags = new List<SwaggerTag>(); if (document.Tags.All(t => t.Name != tag)) document.Tags.Add(new SwaggerTag { Name = tag }); } } } }
private AspNetCoreOperationProcessorContext GetContext(ApiDescription apiDescription) { var operationDescription = new SwaggerOperationDescription { Operation = new SwaggerOperation() }; var swaggerSettings = new AspNetCoreToSwaggerGeneratorSettings(); var document = new SwaggerDocument(); var generator = new AspNetCoreToSwaggerGenerator(swaggerSettings); var schemaGeneratorSettings = new JsonSchemaGeneratorSettings(); var schemaGenerator = new JsonSchemaGenerator(schemaGeneratorSettings); var schemaResolver = new SwaggerSchemaResolver(document, schemaGeneratorSettings); var context = new AspNetCoreOperationProcessorContext( document, operationDescription, GetType(), GetType().GetMethod(nameof(SomeAction), BindingFlags.NonPublic | BindingFlags.Instance), new SwaggerGenerator(schemaGenerator, schemaGeneratorSettings, schemaResolver), schemaGenerator, schemaResolver, swaggerSettings, new List <SwaggerOperationDescription>()) { ApiDescription = apiDescription, }; return(context); }
private bool RunOperationProcessors(MethodInfo method, SwaggerOperationDescription operation, List <SwaggerOperationDescription> allOperations, ISchemaResolver schemaResolver) { // 1. Run from settings foreach (var operationProcessor in Settings.OperationProcessors) { if (operationProcessor.Process(operation, method, schemaResolver, allOperations) == false) { return(false); } } // 2. Run from class attributes var operationProcessorAttribute = method.DeclaringType.GetTypeInfo().GetCustomAttributes() // 3. Run from method attributes .Concat(method.GetCustomAttributes()) .Where(a => a.GetType().Name == "SwaggerOperationProcessorAttribute"); foreach (dynamic attribute in operationProcessorAttribute) { var operationProcessor = Activator.CreateInstance(attribute.Type); if (operationProcessor.Process(method, operation, schemaResolver, allOperations) == false) { return(false); } } return(true); }
private void ProcessSwaggerTagsAttribute(SwaggerDocument document, SwaggerOperationDescription operationDescription, MethodInfo methodInfo) { dynamic tagsAttribute = methodInfo .GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "SwaggerTagsAttribute"); if (tagsAttribute != null) { var tags = ((string[])tagsAttribute.Tags).ToList(); foreach (var tag in tags) { if (operationDescription.Operation.Tags.All(t => t != tag)) { operationDescription.Operation.Tags.Add(tag); } if (ObjectExtensions.HasProperty(tagsAttribute, "AddToDocument") && tagsAttribute.AddToDocument) { if (document.Tags == null) { document.Tags = new List <SwaggerTag>(); } if (document.Tags.All(t => t.Name != tag)) { document.Tags.Add(new SwaggerTag { Name = tag }); } } } } }
private string GetOperationNameFromPath(SwaggerOperationDescription operation) { var pathSegments = operation.Path.Trim('/').Split('/'); var lastPathSegment = pathSegments.LastOrDefault(s => !s.Contains("{")); return(string.IsNullOrEmpty(lastPathSegment) ? "Anonymous" : lastPathSegment); }
private void EnsureSingleBodyParameter(SwaggerOperationDescription operationDescription) { if (operationDescription.Operation.ActualParameters.Count(p => p.Kind == SwaggerParameterKind.Body) > 1) { throw new InvalidOperationException($"The operation '{operationDescription.Operation.OperationId}' has more than one body parameter."); } }
private async Task <bool> RunOperationProcessorsAsync(SwaggerDocument document, Type controllerType, MethodInfo methodInfo, SwaggerOperationDescription operationDescription, List <SwaggerOperationDescription> allOperations, SwaggerGenerator swaggerGenerator) { // 1. Run from settings foreach (var operationProcessor in Settings.OperationProcessors) { if (await operationProcessor.ProcessAsync(new OperationProcessorContext(document, operationDescription, controllerType, methodInfo, swaggerGenerator, allOperations)).ConfigureAwait(false) == false) { return(false); } } // 2. Run from class attributes var operationProcessorAttribute = methodInfo.DeclaringType.GetTypeInfo() .GetCustomAttributes() // 3. Run from method attributes .Concat(methodInfo.GetCustomAttributes()) .Where(a => a.GetType().Name == "SwaggerOperationProcessorAttribute"); foreach (dynamic attribute in operationProcessorAttribute) { var operationProcessor = ObjectExtensions.HasProperty(attribute, "Parameters") ? Activator.CreateInstance(attribute.Type, attribute.Parameters) : Activator.CreateInstance(attribute.Type); if (operationProcessor.Process(methodInfo, operationDescription, swaggerGenerator, allOperations) == false) { return(false); } } return(true); }
private string GetOperationNameFromPath(SwaggerOperationDescription operation) { var pathSegments = operation.Path.Trim('/').Split('/').Where(s => !s.Contains('{')).ToArray(); var lastPathSegment = pathSegments.LastOrDefault(); var path = string.Concat(pathSegments.Take(pathSegments.Length - 1).Select(s => s + "_")); return(path + operation.Method.ToString()[0].ToString().ToUpper() + operation.Method.ToString().Substring(1).ToLower() + ConversionUtilities.ConvertToUpperCamelCase(lastPathSegment.Replace('_', '-'), false)); }
/// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception> private async Task <bool> GenerateForControllerAsync(SwaggerDocument document, Type controllerType, SwaggerGenerator swaggerGenerator, SwaggerSchemaResolver schemaResolver) { var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (hasIgnoreAttribute) { return(false); } var operations = new List <Tuple <SwaggerOperationDescription, MethodInfo> >(); var currentControllerType = controllerType; while (currentControllerType != null) { foreach (var method in GetActionMethods(currentControllerType)) { var httpPaths = GetHttpPaths(controllerType, method).ToList(); var httpMethods = GetSupportedHttpMethods(method).ToList(); foreach (var httpPath in httpPaths) { foreach (var httpMethod in httpMethods) { var isPathAlreadyDefinedInInheritanceHierarchy = operations.Any(o => o.Item1.Path == httpPath && o.Item1.Method == httpMethod && o.Item2.DeclaringType != currentControllerType && o.Item2.DeclaringType.IsAssignableTo(currentControllerType.FullName, TypeNameStyle.FullName)); if (isPathAlreadyDefinedInInheritanceHierarchy == false) { var operationDescription = new SwaggerOperationDescription { Path = httpPath, Method = httpMethod, Operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null, OperationId = GetOperationId(document, controllerType.Name, method) } }; operations.Add(new Tuple <SwaggerOperationDescription, MethodInfo>(operationDescription, method)); } } } } currentControllerType = currentControllerType.GetTypeInfo().BaseType; } return(await AddOperationDescriptionsToDocumentAsync(document, controllerType, operations, swaggerGenerator, schemaResolver).ConfigureAwait(false)); }
private void UpdateConsumedTypes(SwaggerOperationDescription operationDescription) { if (operationDescription.Operation.ActualParameters.Any(p => p.Type == JsonObjectType.File)) { operationDescription.Operation.Consumes = new List <string> { "multipart/form-data" } } ; }
/// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception> private void GenerateForController(SwaggerService service, Type controllerType, string excludedMethodName, ISchemaResolver schemaResolver, ISchemaDefinitionAppender schemaDefinitionAppender) { var hasIgnoreAttribute = controllerType.GetTypeInfo().GetCustomAttributes() .Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (!hasIgnoreAttribute) { var operations = new List <Tuple <SwaggerOperationDescription, MethodInfo> >(); foreach (var method in GetActionMethods(controllerType, excludedMethodName)) { var httpPaths = GetHttpPaths(controllerType, method); var httpMethods = GetSupportedHttpMethods(method).ToList(); foreach (var httpPath in httpPaths) { foreach (var httpMethod in httpMethods) { var operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null }; var parameters = method.GetParameters().ToList(); LoadParameters(operation, parameters, httpPath, schemaResolver, schemaDefinitionAppender); LoadReturnType(operation, method, schemaResolver, schemaDefinitionAppender); LoadMetaData(operation, method); LoadOperationTags(method, operation, controllerType); var operationDescription = new SwaggerOperationDescription { Path = Regex.Replace(httpPath, "{(.*?)(:(.*?))?}", match => { if (operation.ActualParameters.Any(p => p.Kind == SwaggerParameterKind.Path && match.Groups[1].Value == p.Name)) { return("{" + match.Groups[1].Value + "}"); } return(string.Empty); }).TrimEnd('/'), Method = httpMethod, Operation = operation }; operationDescription.Operation.OperationId = GetOperationId(service, controllerType.Name, method); operations.Add(new Tuple <SwaggerOperationDescription, MethodInfo>(operationDescription, method)); } } } AddOperationDescriptionsToDocument(service, operations, schemaResolver); } AppendRequiredSchemasToDefinitions(service, schemaResolver); }
private async Task GenerateForControllerAsync(SwaggerDocument document, Type controllerType, IEnumerable <Tuple <ApiDescription, MethodInfo> > controllerApiDescriptionGroup, SwaggerGenerator swaggerGenerator, SwaggerSchemaResolver schemaResolver) { var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (hasIgnoreAttribute) { return; } var operations = new List <Tuple <SwaggerOperationDescription, ApiDescription, MethodInfo> >(); var descriptions = new List <SwaggerOperationDescription>(); foreach (var item in controllerApiDescriptionGroup) { var apiDescription = item.Item1; var method = item.Item2; var actionHasIgnoreAttribute = method.GetCustomAttributes().Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (actionHasIgnoreAttribute) { continue; } var path = apiDescription.RelativePath; if (!path.StartsWith("/", StringComparison.Ordinal)) { path = "/" + path; } var controllerActionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor; if (!Enum.TryParse <SwaggerOperationMethod>(apiDescription.HttpMethod, ignoreCase: true, result: out var swaggerOperationMethod)) { swaggerOperationMethod = SwaggerOperationMethod.Undefined; } var operationDescription = new SwaggerOperationDescription { Path = path, Method = swaggerOperationMethod, Operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null, OperationId = GetOperationId(document, controllerActionDescriptor, method) } }; operations.Add(new Tuple <SwaggerOperationDescription, ApiDescription, MethodInfo>(operationDescription, apiDescription, method)); } await AddOperationDescriptionsToDocumentAsync(document, controllerType, operations, swaggerGenerator, schemaResolver).ConfigureAwait(false); }
private void RemoveUnusedPathParameters(SwaggerOperationDescription operationDescription, string httpPath) { operationDescription.Path = Regex.Replace(httpPath, "{(.*?)(:(([^/]*)?))?}", match => { var parameterName = match.Groups[1].Value.TrimEnd('?'); if (operationDescription.Operation.ActualParameters.Any(p => p.Kind == SwaggerParameterKind.Path && string.Equals(p.Name, parameterName, StringComparison.OrdinalIgnoreCase))) { return("{" + parameterName + "}"); } return(string.Empty); }).TrimEnd('/'); }
private static string GetPathExpression(SwaggerOperationDescription operation) { string pathExpression = operation.Path; if (pathExpression.StartsWith("/")) { pathExpression = pathExpression.Substring(1); } pathExpression = pathExpression.Replace("{namespace}", "{@namespace}"); return(pathExpression); }
private static string GetPathExpression(SwaggerOperationDescription operation) { var pathExpression = operation.Path; if (pathExpression.StartsWith("/", StringComparison.InvariantCulture)) { pathExpression = pathExpression.Substring(1); } pathExpression = pathExpression.Replace("{namespace}", "{@namespace}"); return(pathExpression); }
/// <summary>Initializes a new instance of the <see cref="AspNetCoreOperationProcessorContext" /> class.</summary> /// <param name="document">The document.</param> /// <param name="operationDescription">The operation description.</param> /// <param name="controllerType">Type of the controller.</param> /// <param name="methodInfo">The method information.</param> /// <param name="swaggerGenerator">The swagger generator.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <param name="settings">The sett</param> /// <param name="allOperationDescriptions">All operation descriptions.</param> /// <param name="schemaGenerator">The schema generator.</param> public AspNetCoreOperationProcessorContext( SwaggerDocument document, SwaggerOperationDescription operationDescription, Type controllerType, MethodInfo methodInfo, SwaggerGenerator swaggerGenerator, JsonSchemaGenerator schemaGenerator, JsonSchemaResolver schemaResolver, SwaggerGeneratorSettings settings, IList <SwaggerOperationDescription> allOperationDescriptions) : base(document, operationDescription, controllerType, methodInfo, swaggerGenerator, schemaGenerator, schemaResolver, settings, allOperationDescriptions) { }
/// <summary>Initializes a new instance of the <see cref="OperationProcessorContext"/> class.</summary> /// <param name="document">The document.</param> /// <param name="operationDescription">The operation description.</param> /// <param name="methodInfo">The method information.</param> /// <param name="swaggerGenerator">The swagger generator.</param> /// <param name="allOperationDescriptions">All operation descriptions.</param> public OperationProcessorContext( SwaggerDocument document, SwaggerOperationDescription operationDescription, MethodInfo methodInfo, SwaggerGenerator swaggerGenerator, IList <SwaggerOperationDescription> allOperationDescriptions) { Document = document; OperationDescription = operationDescription; MethodInfo = methodInfo; SwaggerGenerator = swaggerGenerator; AllOperationDescriptions = allOperationDescriptions; }
/// <summary>Gets the security scopes for an operation.</summary> /// <param name="operationDescription">The operation description.</param> /// <param name="methodInfo">The method information.</param> /// <returns>The scopes.</returns> protected virtual IEnumerable<string> GetScopes(SwaggerOperationDescription operationDescription, MethodInfo methodInfo) { var allAttributes = methodInfo.GetCustomAttributes().Concat( methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes()); var authorizeAttributes = allAttributes.Where(a => a.GetType().Name == "AuthorizeAttribute").ToList(); if (!authorizeAttributes.Any()) return Enumerable.Empty<string>(); return authorizeAttributes .Select(a => (dynamic)a) .Where(a => a.Roles != null) .SelectMany(a => ((string)a.Roles).Split(',')) .Distinct(); }
private void ProcessSwaggerTagAttributes(SwaggerDocument document, SwaggerOperationDescription operationDescription, MethodInfo methodInfo) { foreach (var tagAttribute in methodInfo.GetCustomAttributes() .Where(a => a.GetType().Name == "SwaggerTagAttribute") .Select(a => (dynamic)a)) { if (operationDescription.Operation.Tags.All(t => t != tagAttribute.Name)) { operationDescription.Operation.Tags.Add(tagAttribute.Name); } if (ReflectionExtensions.HasProperty(tagAttribute, "AddToDocument") && tagAttribute.AddToDocument) { DocumentTagsProcessor.AddTagFromSwaggerTagAttribute(document, tagAttribute); } } }
/// <summary>Gets the security scopes for an operation.</summary> /// <param name="operationDescription">The operation description.</param> /// <param name="methodInfo">The method information.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <param name="allOperationDescriptions">All operation descriptions.</param> /// <returns>The scopes.</returns> protected virtual IEnumerable <string> GetScopes(SwaggerOperationDescription operationDescription, MethodInfo methodInfo, ISchemaResolver schemaResolver, IList <SwaggerOperationDescription> allOperationDescriptions) { var allAttributes = methodInfo.GetCustomAttributes().Concat( methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes()); var authorizeAttributes = allAttributes.Where(a => a.GetType().Name == "AuthorizeAttribute").ToList(); if (!authorizeAttributes.Any()) { return(Enumerable.Empty <string>()); } return(authorizeAttributes .SelectMany((dynamic attr) => ((string)attr.Roles).Split(',')) .Distinct()); }
/// <summary>Processes the specified method information.</summary> /// <param name="operationDescription">The operation description.</param> /// <param name="methodInfo">The method information.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <param name="allOperationDescriptions">All operation descriptions.</param> /// <returns>true if the operation should be added to the Swagger specification.</returns> public bool Process(SwaggerOperationDescription operationDescription, MethodInfo methodInfo, ISchemaResolver schemaResolver, IList <SwaggerOperationDescription> allOperationDescriptions) { if (operationDescription.Operation.Security == null) { operationDescription.Operation.Security = new List <SwaggerSecurityRequirement>(); } var scopes = GetScopes(operationDescription, methodInfo, schemaResolver, allOperationDescriptions); operationDescription.Operation.Security.Add(new SwaggerSecurityRequirement { { _name, scopes } }); return(true); }
/// <summary>Initializes a new instance of the <see cref="OperationProcessorContext" /> class.</summary> /// <param name="document">The document.</param> /// <param name="operationDescription">The operation description.</param> /// <param name="controllerType">Type of the controller.</param> /// <param name="methodInfo">The method information.</param> /// <param name="swaggerGenerator">The swagger generator.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <param name="allOperationDescriptions">All operation descriptions.</param> /// <param name="schemaGenerator">The schema generator.</param> public OperationProcessorContext( SwaggerDocument document, SwaggerOperationDescription operationDescription, Type controllerType, MethodInfo methodInfo, SwaggerGenerator swaggerGenerator, JsonSchemaGenerator schemaGenerator, JsonSchemaResolver schemaResolver, IList <SwaggerOperationDescription> allOperationDescriptions) { Document = document; OperationDescription = operationDescription; ControllerType = controllerType; MethodInfo = methodInfo; SwaggerGenerator = swaggerGenerator; SchemaResolver = schemaResolver; SchemaGenerator = schemaGenerator; AllOperationDescriptions = allOperationDescriptions; }
private void ProcessSwaggerTagAttributes(SwaggerDocument document, SwaggerOperationDescription operationDescription, MethodInfo methodInfo) { var tagAttributes = methodInfo.GetCustomAttributes() .Where(a => a.GetType().Name == "SwaggerTagAttribute") .Select(a => (dynamic)a) .ToArray(); if (tagAttributes.Any()) { foreach (var tagAttribute in tagAttributes) { if (operationDescription.Operation.Tags.All(t => t != tagAttribute.Name)) operationDescription.Operation.Tags.Add(tagAttribute.Name); if (ObjectExtensions.HasProperty(tagAttribute, "AddToDocument") && tagAttribute.AddToDocument) DocumentTagsProcessor.AddTagFromSwaggerTagAttribute(document, tagAttribute); } } }
/// <summary> /// Create a Action based on information from the Swagger file /// </summary> /// <param name="action">A description of the endpoint generated by the Swagger class</param> public Action(SwaggerOperationDescription action) { Route = action.Path.Trim('/').ToLower(); Method = action.Method.ToString().ToUpper(); //HttpAttributes HttpMethods are all Uppercase var parameters = action.Operation.ActualParameters; //ICollection<SwaggerParameter> complex = new List<SwaggerParameter>(); //simple params foreach (var parameter in parameters) { if (parameter.Type.ToString() != "None") //If it's not a complex type { simpleParams.Add(parameter.Name.ToLower(), parameter.Type.ToString().ToLower()); //typeof for primitives are all lower } else { complexParams.Add(parameter.Name.ToLower(), parameter.ActualSchema); } } }
/// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception> private void GenerateForController(SwaggerDocument document, Type controllerType, SwaggerGenerator swaggerGenerator) { var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .Any(a => a.GetType().Name == Settings.SwaggerIgnoreAttribute); if (hasIgnoreAttribute) { return; } var operations = new List <Tuple <SwaggerOperationDescription, MethodInfo> >(); foreach (var method in GetActionMethods(controllerType)) { var httpPaths = GetHttpPaths(controllerType, method).ToList(); var httpMethods = GetSupportedHttpMethods(method).ToList(); foreach (var httpPath in httpPaths) { foreach (var httpMethod in httpMethods) { var operationDescription = new SwaggerOperationDescription { Path = httpPath, Method = httpMethod, Operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null, OperationId = GetOperationId(document, controllerType.Name, method) } }; operations.Add(new Tuple <SwaggerOperationDescription, MethodInfo>(operationDescription, method)); } } } AddOperationDescriptionsToDocument(document, operations, swaggerGenerator); }
/// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception> private async Task GenerateForControllerAsync(SwaggerDocument document, Type controllerType, SwaggerGenerator swaggerGenerator, SwaggerSchemaResolver schemaResolver) { // System.Console.WriteLine($"Controller: {controllerType}"); var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .Any(a => a.GetType().Name == "SwaggerIgnoreAttribute"); if (!hasIgnoreAttribute) { var operations = new List <Tuple <SwaggerOperationDescription, MethodInfo> >(); foreach (var method in GetActionMethods(controllerType)) { var httpPaths = GetHttpPaths(controllerType, method).ToList(); var httpMethods = GetSupportedHttpMethods(method).ToList(); foreach (var httpPath in httpPaths) { foreach (var httpMethod in httpMethods) { var operationDescription = new SwaggerOperationDescription { Path = httpPath, Method = httpMethod, Operation = new SwaggerOperation { IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null, OperationId = GetOperationId(document, controllerType.Name, method) } }; operations.Add(new Tuple <SwaggerOperationDescription, MethodInfo>(operationDescription, method)); } } } await AddOperationDescriptionsToDocumentAsync(document, controllerType, operations, swaggerGenerator, schemaResolver).ConfigureAwait(false); } }
private void EnsureSingleBodyParameter(SwaggerOperationDescription operationDescription) { if (operationDescription.Operation.ActualParameters.Count(p => p.Kind == SwaggerParameterKind.Body) > 1) throw new InvalidOperationException("The operation '" + operationDescription.Operation.OperationId + "' has more than one body parameter."); }
private async Task <bool> RunOperationProcessorsAsync(SwaggerDocument document, ApiDescription apiDescription, Type controllerType, MethodInfo methodInfo, SwaggerOperationDescription operationDescription, List <SwaggerOperationDescription> allOperations, SwaggerGenerator swaggerGenerator, SwaggerSchemaResolver schemaResolver) { // 1. Run from settings var operationProcessorContext = new AspNetCoreOperationProcessorContext(document, operationDescription, controllerType, methodInfo, swaggerGenerator, _schemaGenerator, schemaResolver, Settings, allOperations) { ApiDescription = apiDescription, }; foreach (var operationProcessor in Settings.OperationProcessors) { if (await operationProcessor.ProcessAsync(operationProcessorContext).ConfigureAwait(false) == false) { return(false); } } // 2. Run from class attributes var operationProcessorAttribute = methodInfo.DeclaringType.GetTypeInfo() .GetCustomAttributes() // 3. Run from method attributes .Concat(methodInfo.GetCustomAttributes()) .Where(a => a.GetType().IsAssignableTo("SwaggerOperationProcessorAttribute", TypeNameStyle.Name)); foreach (dynamic attribute in operationProcessorAttribute) { var operationProcessor = ReflectionExtensions.HasProperty(attribute, "Parameters") ? (IOperationProcessor)Activator.CreateInstance(attribute.Type, attribute.Parameters) : (IOperationProcessor)Activator.CreateInstance(attribute.Type); if (await operationProcessor.ProcessAsync(operationProcessorContext) == false) { return(false); } } return(true); }
private void ReplaceApiVersionInPath(SwaggerOperationDescription operationDescription, dynamic versions) { operationDescription.Path = operationDescription.Path.Replace("{version:apiVersion}", versions[0].ToString()); }
private void UpdateConsumedTypes(SwaggerOperationDescription operationDescription) { if (operationDescription.Operation.ActualParameters.Any(p => p.Type == JsonObjectType.File)) operationDescription.Operation.Consumes = new List<string> { "multipart/form-data" }; }
private void RemoveUnusedPathParameters(SwaggerOperationDescription operationDescription, string httpPath) { operationDescription.Path = Regex.Replace(httpPath, "{(.*?)(:(([^/]*)?))?}", match => { var parameterName = match.Groups[1].Value.TrimEnd('?'); if (operationDescription.Operation.ActualParameters.Any(p => p.Kind == SwaggerParameterKind.Path && string.Equals(p.Name, parameterName, StringComparison.OrdinalIgnoreCase))) return "{" + parameterName + "}"; return string.Empty; }).TrimEnd('/'); }