/// <summary>
        /// Generates Swagger document for the specified Azure Function classes, including only the listed Functions.
        /// </summary>
        /// <param name="azureFunctionClassTypes">The Azure Function classes (static classes)</param>
        /// <param name="functionNames">The function names (defined by FunctionNameAttribute)</param>
        /// <returns>The generated Swagger document</returns>
        public async Task <OpenApiDocument> GenerateForAzureFunctionClassesAsync(IEnumerable <Type> azureFunctionClassTypes,
                                                                                 IList <string> functionNames)
        {
            var document = await CreateDocumentAsync().ConfigureAwait(false);

            var schemaResolver = new OpenApiSchemaResolver(document, Settings);
            var usedAzureFunctionClassTypes = new List <Type>();

            foreach (var azureFunctionClassType in azureFunctionClassTypes)
            {
                var generator  = new OpenApiDocumentGenerator(Settings, schemaResolver);
                var isIncluded = await GenerateForAzureFunctionClassAsync(document, azureFunctionClassType,
                                                                          generator, schemaResolver, functionNames);

                if (isIncluded)
                {
                    usedAzureFunctionClassTypes.Add(azureFunctionClassType);
                }
            }

            document.GenerateOperationIds();

            foreach (var processor in Settings.DocumentProcessors)
            {
                processor.Process(new DocumentProcessorContext(document, azureFunctionClassTypes,
                                                               usedAzureFunctionClassTypes, schemaResolver, Settings.SchemaGenerator, Settings));
            }

            return(document);
        }
        private async Task <bool> GenerateForAzureFunctionClassAsync(OpenApiDocument document, Type staticAzureFunctionClassType,
                                                                     OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver, IList <string> functionNames)
        {
            var operations = new List <Tuple <OpenApiOperationDescription, MethodInfo> >();

            foreach (var method in GetActionMethods(staticAzureFunctionClassType, functionNames))
            {
                var httpPaths   = GetHttpPaths(method);
                var httpMethods = GetSupportedHttpMethods(method);

                foreach (var httpPath in httpPaths)
                {
                    foreach (var httpMethod in httpMethods)
                    {
                        var operationDescription = new OpenApiOperationDescription
                        {
                            Path      = httpPath,
                            Method    = httpMethod,
                            Operation = new OpenApiOperation
                            {
                                IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null,
                                OperationId  = GetOperationId(document, staticAzureFunctionClassType.Name, method)
                            }
                        };

                        operations.Add(new Tuple <OpenApiOperationDescription, MethodInfo>(operationDescription, method));
                    }
                }
            }

            return(await AddOperationDescriptionsToDocumentAsync(document, staticAzureFunctionClassType, operations,
                                                                 swaggerGenerator, schemaResolver));
        }
Пример #3
0
        /// <summary>Generates a Swagger specification for the given controller types.</summary>
        /// <param name="controllerTypes">The types of the controller.</param>
        /// <returns>The <see cref="OpenApiDocument" />.</returns>
        /// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception>
        public async Task <OpenApiDocument> GenerateForControllersAsync(IEnumerable <Type> controllerTypes)
        {
            var document = await CreateDocumentAsync().ConfigureAwait(false);

            var schemaResolver = new OpenApiSchemaResolver(document, Settings);

            var usedControllerTypes = new List <Type>();

            foreach (var controllerType in controllerTypes)
            {
                var generator  = new OpenApiDocumentGenerator(Settings, schemaResolver);
                var isIncluded = GenerateForController(document, controllerType, generator, schemaResolver);
                if (isIncluded)
                {
                    usedControllerTypes.Add(controllerType);
                }
            }

            document.GenerateOperationIds();

            foreach (var processor in Settings.DocumentProcessors)
            {
                processor.Process(new DocumentProcessorContext(document, controllerTypes,
                                                               usedControllerTypes, schemaResolver, Settings.SchemaGenerator, Settings));
            }

            return(document);
        }
Пример #4
0
        public async Task <OpenApiDocument> GenerateDocument(Assembly assembly)
        {
            var document = await CreateDocumentAsync().ConfigureAwait(false);

            var schemaResolver = new OpenApiSchemaResolver(document, Settings);

            var handlerTypes     = GetAllHandlerTypes(assembly);
            var usedHandlerTypes = new List <Type>();

            foreach (var handlerType in handlerTypes)
            {
                var generator  = new OpenApiDocumentGenerator(Settings, schemaResolver);
                var isIncluded = GenerateForHandler(document, handlerType, generator, schemaResolver);
                if (isIncluded)
                {
                    usedHandlerTypes.Add(handlerType);
                }
            }

            document.GenerateOperationIds();

            foreach (var processor in Settings.DocumentProcessors)
            {
                processor.Process(new DocumentProcessorContext(document, handlerTypes,
                                                               usedHandlerTypes, schemaResolver, Settings.SchemaGenerator, Settings));
            }

            return(document);
        }
Пример #5
0
 /// <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(
     OpenApiDocument document,
     OpenApiOperationDescription operationDescription,
     Type controllerType,
     MethodInfo methodInfo,
     OpenApiDocumentGenerator swaggerGenerator,
     JsonSchemaGenerator schemaGenerator,
     JsonSchemaResolver schemaResolver,
     OpenApiDocumentGeneratorSettings settings,
     IList <OpenApiOperationDescription> allOperationDescriptions)
     : base(document, operationDescription, controllerType, methodInfo, swaggerGenerator, schemaGenerator, schemaResolver, settings, allOperationDescriptions)
 {
 }
        private OpenApiParameter GetParameter(SchemaType schemaType)
        {
            var generatorSettings = new OpenApiDocumentGeneratorSettings
            {
                SchemaType        = schemaType,
                ReflectionService = new DefaultReflectionService()
            };
            var schemaResolver = new JsonSchemaResolver(new OpenApiDocument(), generatorSettings);
            var generator      = new OpenApiDocumentGenerator(generatorSettings, schemaResolver);
            var methodInfo     = typeof(TestController).GetMethod("HasArrayParameter");

            return(generator.CreatePrimitiveParameter("foo", "bar", methodInfo.GetContextualParameters().First()));
        }
Пример #7
0
        private List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> > AddOperationDescriptionsToDocument(
            OpenApiDocument document, Type controllerType,
            List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> > operations,
            OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            var addedOperations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >();
            var allOperations   = new List <OpenApiOperationDescription>(operations.Count);

            allOperations.AddRange(operations.Select(t => t.Item1));

            foreach (var tuple in operations)
            {
                var operation      = tuple.Item1;
                var apiDescription = tuple.Item2;
                var method         = tuple.Item3;

                var addOperation = RunOperationProcessors(
                    document,
                    apiDescription,
                    controllerType,
                    method,
                    operation,
                    allOperations,
                    swaggerGenerator,
                    schemaResolver);

                if (addOperation)
                {
                    var path = operation.Path.Replace("//", "/");
                    if (!document.Paths.TryGetValue(path, out var pathItem))
                    {
                        document.Paths[path] = pathItem = new OpenApiPathItem();
                    }

                    if (pathItem.ContainsKey(operation.Method))
                    {
                        throw new InvalidOperationException($"The method '{operation.Method}' on path '{path}' is registered multiple times.");
                    }

                    pathItem[operation.Method] = operation.Operation;
                    addedOperations.Add(tuple);
                }
            }

            return(addedOperations);
        }
        public void Can_Correctly_Generate_A_Schema()
        {
            var generator = new OpenApiDocumentGenerator();

            var doc = generator.GenerateOpenApiDocument(new ApiMetadata {
                Title       = "Test Api",
                Description = "My Test Api",
                Version     = "1.0.0.0",
                Url         = "http://localhost:7071/api/"
            }, typeof(MyTestFunction).Assembly, new HashSet <Type> {
                typeof(ILogger),
                typeof(HttpRequest),
                typeof(HttpTriggerAttribute)
            });

            using (var fs = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), "test_openapi.json")))
                using (var sw = new StreamWriter(fs))
                {
                    doc.SerializeAsV2(new OpenApiJsonWriter(sw));
                }

            // Assert.NotEmpty(funcs);

            // var func = funcs.Single();

            // Assert.Equal("TestHttpTrigger", func.Name);
            // Assert.Equal(OperationType.Get, func.Methods.Single());
            // Assert.Equal(5, func.Returns.Length);
            // Assert.Collection(func.Returns, new Action<ReturnsAttribute>[] {
            //     a => { Assert.Equal(200, a.StatusCode); Assert.Equal("OK", a.Description); Assert.Equal(typeof(TestType), a.BodyType); },
            //     a => { Assert.Equal(400, a.StatusCode); Assert.Equal("Bad", a.Description); },
            //     a => { Assert.Equal(404, a.StatusCode); Assert.Equal("NotFound", a.Description); },
            //     a => { Assert.Equal(401, a.StatusCode); Assert.Equal("Unauthorized", a.Description); },
            //     a => { Assert.Equal(403, a.StatusCode); Assert.Equal("Forbidden", a.Description); },
            // });
            // Assert.Equal("/api/result/{sessionId}", func.Route);
            // Assert.Single(func.Parameters);
            // Assert.Collection(func.Parameters, new Action<ParameterInfo>[] {
            //     p => { Assert.Equal("sessionId", p.Name); Assert.Equal(typeof(String), p.ParameterType); }
            // });
        }
Пример #9
0
        private bool GenerateForHandler(OpenApiDocument document, Type handlerType, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            var methodInfo = handlerType.GetMethod("Handle");
            var isQuery    = handlerType.IsAssignableToGenericType(typeof(IQueryRequestHandler <,>));

            var httpMethod = isQuery ? OpenApiOperationMethod.Get : OpenApiOperationMethod.Post;
            var httpPath   = $"/rpc/{GetRequestTypeFullName(methodInfo)}";

            var operationDescription = new OpenApiOperationDescription
            {
                Path      = httpPath,
                Method    = httpMethod,
                Operation = new OpenApiOperation
                {
                    IsDeprecated = methodInfo.GetCustomAttribute <ObsoleteAttribute>() != null,
                    OperationId  = GetOperationId(document, handlerType.Name)
                }
            };

            return(AddOperationDescriptionsToDocumentAsync(document, handlerType, (operationDescription, methodInfo), swaggerGenerator, schemaResolver));
        }
Пример #10
0
        /// <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="openApiDocumentGenerator">The swagger generator.</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <param name="settings">The settings.</param>
        /// <param name="allOperationDescriptions">All operation descriptions.</param>
        /// <param name="schemaGenerator">The schema generator.</param>
        public OperationProcessorContext(
            OpenApiDocument document,
            OpenApiOperationDescription operationDescription,
            Type controllerType,
            MethodInfo methodInfo,
            OpenApiDocumentGenerator openApiDocumentGenerator,
            JsonSchemaGenerator schemaGenerator,
            JsonSchemaResolver schemaResolver,
            OpenApiDocumentGeneratorSettings settings,
            IList <OpenApiOperationDescription> allOperationDescriptions)
        {
            Document = document;

            OperationDescription = operationDescription;
            ControllerType       = controllerType;
            MethodInfo           = methodInfo;

            DocumentGenerator = openApiDocumentGenerator;
            SchemaGenerator   = schemaGenerator;
            SchemaResolver    = schemaResolver;

            Settings = settings;
            AllOperationDescriptions = allOperationDescriptions;
        }
Пример #11
0
        private List <Type> GenerateApiGroups(
            OpenApiDocument document,
            IGrouping <Type, Tuple <ApiDescription, ActionDescriptor> >[] apiGroups,
            OpenApiSchemaResolver schemaResolver)
        {
            var usedControllerTypes = new List <Type>();
            var swaggerGenerator    = new OpenApiDocumentGenerator(Settings, schemaResolver);

            var allOperations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >();

            foreach (var apiGroup in apiGroups)
            {
                var controllerType = apiGroup.Key;

                var hasIgnoreAttribute = controllerType != null && controllerType
                                         .GetTypeInfo()
                                         .GetCustomAttributes()
                                         .GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name)
                                         .Any();

                if (!hasIgnoreAttribute)
                {
                    var operations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >();
                    foreach (var item in apiGroup)
                    {
                        var apiDescription = item.Item1;
                        if (apiDescription.RelativePath == null)
                        {
                            continue;
                        }

                        var method = (item.Item2 as ControllerActionDescriptor)?.MethodInfo;
                        if (method != null)
                        {
                            var actionHasIgnoreAttribute = method.GetCustomAttributes().GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name).Any();
                            if (actionHasIgnoreAttribute)
                            {
                                continue;
                            }
                        }

                        var path = apiDescription.RelativePath;
                        if (!path.StartsWith("/", StringComparison.Ordinal))
                        {
                            path = "/" + path;
                        }

                        var httpMethod = apiDescription.HttpMethod?.ToLowerInvariant() ?? (apiDescription.ParameterDescriptions.Where(p =>
                        {
                            return(p.Source == Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource.Body);
                        }).Count() > 0 ? OpenApiOperationMethod.Post : OpenApiOperationMethod.Get);

                        var operationDescription = new OpenApiOperationDescription
                        {
                            Path      = path,
                            Method    = httpMethod,
                            Operation = new OpenApiOperation
                            {
                                IsDeprecated = IsOperationDeprecated(item.Item1, apiDescription.ActionDescriptor, method),
                                OperationId  = GetOperationId(document, apiDescription, method, httpMethod),
                                Consumes     = apiDescription.SupportedRequestFormats
                                               .Select(f => f.MediaType)
                                               .Distinct()
                                               .ToList(),
                                Produces = apiDescription.SupportedResponseTypes
                                           .SelectMany(t => t.ApiResponseFormats.Select(f => f.MediaType))
                                           .Distinct()
                                           .ToList()
                            }
                        };

                        operations.Add(new Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo>(operationDescription, apiDescription, method));
                    }

                    var addedOperations = AddOperationDescriptionsToDocument(document, controllerType, operations, swaggerGenerator, schemaResolver);
                    if (addedOperations.Any() && apiGroup.Key != null)
                    {
                        usedControllerTypes.Add(apiGroup.Key);
                    }

                    allOperations.AddRange(addedOperations);
                }
            }

            UpdateConsumesAndProduces(document, allOperations);
            return(usedControllerTypes);
        }
        private async Task <bool> AddOperationDescriptionsToDocumentAsync(OpenApiDocument document, Type staticAzureFunctionClassType,
                                                                          List <Tuple <OpenApiOperationDescription, MethodInfo> > operations, OpenApiDocumentGenerator swaggerGenerator,
                                                                          OpenApiSchemaResolver schemaResolver)
        {
            var addedOperations = 0;
            var allOps          = operations.Select(t => t.Item1).ToList();

            foreach (var o in operations)
            {
                var operation = o.Item1;
                var method    = o.Item2;

                var addOperation = await RunOperationProcessorsAsync(document, staticAzureFunctionClassType, method,
                                                                     operation, allOps, swaggerGenerator, schemaResolver);

                if (addOperation)
                {
                    var path = operation.Path.Replace("//", "/");

                    if (!document.Paths.ContainsKey(path))
                    {
                        document.Paths[path] = new OpenApiPathItem();
                    }

                    if (document.Paths[path].ContainsKey(operation.Method))
                    {
                        throw new InvalidOperationException("The method '" + operation.Method + "' on path '" + path + "' is registered multiple times");
                    }

                    document.Paths[path][operation.Method] = operation.Operation;
                    addedOperations++;
                }
            }

            return(addedOperations > 0);
        }
Пример #13
0
        /// <exception cref="InvalidOperationException">The operation has more than one body parameter.</exception>
        private bool GenerateForController(OpenApiDocument document, Type controllerType, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            var hasIgnoreAttribute = controllerType.GetTypeInfo()
                                     .GetCustomAttributes()
                                     .GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name)
                                     .Any();

            if (hasIgnoreAttribute)
            {
                return(false);
            }

            var operations = new List <Tuple <OpenApiOperationDescription, 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.IsAssignableToTypeName(currentControllerType.FullName, TypeNameStyle.FullName));

                            if (isPathAlreadyDefinedInInheritanceHierarchy == false)
                            {
                                var operationDescription = new OpenApiOperationDescription
                                {
                                    Path      = httpPath,
                                    Method    = httpMethod,
                                    Operation = new OpenApiOperation
                                    {
                                        IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null,
                                        OperationId  = GetOperationId(document, controllerType.Name, method, httpMethod)
                                    }
                                };

                                operations.Add(new Tuple <OpenApiOperationDescription, MethodInfo>(operationDescription, method));
                            }
                        }
                    }
                }

                currentControllerType = currentControllerType.GetTypeInfo().BaseType;
            }

            return(AddOperationDescriptionsToDocument(document, controllerType, operations, swaggerGenerator, schemaResolver));
        }
        private bool AddOperationDescriptionsToDocument(OpenApiDocument document, Type controllerType, List <Tuple <OpenApiOperationDescription, MethodInfo> > operations, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            var addedOperations = 0;
            var allOperation    = operations.Select(t => t.Item1).ToList();

            foreach (var tuple in operations)
            {
                var operation = tuple.Item1;
                var method    = tuple.Item2;

                var addOperation = RunOperationProcessors(document, controllerType, method, operation, allOperation, swaggerGenerator, schemaResolver);
                if (addOperation)
                {
                    var path = operation.Path.Replace("//", "/");

                    // iiQ Custom
                    // .. Prevents "The method 'get' on path '/v1.0' is registered multiple times" exception
                    // .. Also guards for root pathed URLs such as "/v1.0" since all URLs are versioned in iiQ
                    if (path.Split(new char[] { '/' }).Length <= 2)
                    {
                        continue;
                    }

                    if (!document.Paths.ContainsKey(path))
                    {
                        document.Paths[path] = new OpenApiPathItem();
                    }

                    if (document.Paths[path].ContainsKey(operation.Method))
                    {
                        throw new InvalidOperationException("The method '" + operation.Method + "' on path '" + path + "' is registered multiple times " +
                                                            "(check the DefaultUrlTemplate setting [default for Web API: 'api/{controller}/{id}'; for MVC projects: '{controller}/{action}/{id?}']).");
                    }

                    document.Paths[path][operation.Method] = operation.Operation;
                    addedOperations++;
                }
            }

            return(addedOperations > 0);
        }
        private List <Type> GenerateForControllers(
            OpenApiDocument document,
            IGrouping <Type, Tuple <ApiDescription, ControllerActionDescriptor> >[] apiGroups,
            OpenApiSchemaResolver schemaResolver)
        {
            var usedControllerTypes = new List <Type>();
            var swaggerGenerator    = new OpenApiDocumentGenerator(Settings, schemaResolver);

            var allOperations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >();

            foreach (var controllerApiDescriptionGroup in apiGroups)
            {
                var controllerType = controllerApiDescriptionGroup.Key;

                var hasIgnoreAttribute = controllerType.GetTypeInfo()
                                         .GetCustomAttributes()
                                         .GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name)
                                         .Any();

                if (!hasIgnoreAttribute)
                {
                    var operations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >();
                    foreach (var item in controllerApiDescriptionGroup)
                    {
                        var apiDescription = item.Item1;
                        var method         = item.Item2.MethodInfo;

                        var actionHasIgnoreAttribute = method.GetCustomAttributes().GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name).Any();
                        if (actionHasIgnoreAttribute)
                        {
                            continue;
                        }

                        var path = apiDescription.RelativePath;
                        if (!path.StartsWith("/", StringComparison.Ordinal))
                        {
                            path = "/" + path;
                        }

                        var controllerActionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor;
                        var httpMethod = apiDescription.HttpMethod?.ToLowerInvariant() ?? OpenApiOperationMethod.Get;

                        var operationDescription = new OpenApiOperationDescription
                        {
                            Path      = path,
                            Method    = httpMethod,
                            Operation = new OpenApiOperation
                            {
                                IsDeprecated = method.GetCustomAttribute <ObsoleteAttribute>() != null,
                                OperationId  = GetOperationId(document, controllerActionDescriptor, method),
                                Consumes     = apiDescription.SupportedRequestFormats
                                               .Select(f => f.MediaType)
                                               .Distinct()
                                               .ToList(),
                                Produces = apiDescription.SupportedResponseTypes
                                           .SelectMany(t => t.ApiResponseFormats.Select(f => f.MediaType))
                                           .Distinct()
                                           .ToList()
                            }
                        };

                        operations.Add(new Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo>(operationDescription, apiDescription, method));
                    }

                    var addedOperations = AddOperationDescriptionsToDocument(document, controllerType, operations, swaggerGenerator, schemaResolver);
                    if (addedOperations.Any())
                    {
                        usedControllerTypes.Add(controllerApiDescriptionGroup.Key);
                    }

                    allOperations.AddRange(addedOperations);
                }
            }

            UpdateConsumesAndProduces(document, allOperations);
            return(usedControllerTypes);
        }
        private bool RunOperationProcessors(OpenApiDocument document, ApiDescription apiDescription, Type controllerType, MethodInfo methodInfo, OpenApiOperationDescription operationDescription, List <OpenApiOperationDescription> allOperations, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            // 1. Run from settings
            var operationProcessorContext = new AspNetCoreOperationProcessorContext(document, operationDescription, controllerType, methodInfo, swaggerGenerator, Settings.SchemaGenerator, schemaResolver, Settings, allOperations)
            {
                ApiDescription = apiDescription,
            };

            foreach (var operationProcessor in Settings.OperationProcessors)
            {
                if (operationProcessor.Process(operationProcessorContext) == 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().IsAssignableToTypeName("SwaggerOperationProcessorAttribute", TypeNameStyle.Name));

            foreach (dynamic attribute in operationProcessorAttribute)
            {
                var operationProcessor = ObjectExtensions.HasProperty(attribute, "Parameters") ?
                                         (IOperationProcessor)Activator.CreateInstance(attribute.Type, attribute.Parameters) :
                                         (IOperationProcessor)Activator.CreateInstance(attribute.Type);

                if (operationProcessor.Process(operationProcessorContext) == false)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #17
0
        private bool AddOperationDescriptionsToDocument(OpenApiDocument document, Type controllerType, List <Tuple <OpenApiOperationDescription, MethodInfo> > operations, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver)
        {
            var addedOperations = 0;
            var allOperation    = operations.Select(t => t.Item1).ToList();

            foreach (var tuple in operations)
            {
                var operation = tuple.Item1;
                var method    = tuple.Item2;

                var addOperation = RunOperationProcessors(document, controllerType, method, operation, allOperation, swaggerGenerator, schemaResolver);
                if (addOperation)
                {
                    var path = operation.Path.Replace("//", "/");

                    if (!document.Paths.ContainsKey(path))
                    {
                        document.Paths[path] = new OpenApiPathItem();
                    }

                    if (document.Paths[path].ContainsKey(operation.Method))
                    {
                        throw new InvalidOperationException("The method '" + operation.Method + "' on path '" + path + "' is registered multiple times " +
                                                            "(check the DefaultUrlTemplate setting [default for Web API: 'api/{controller}/{id}'; for MVC projects: '{controller}/{action}/{id?}']).");
                    }

                    document.Paths[path][operation.Method] = operation.Operation;
                    addedOperations++;
                }
            }

            return(addedOperations > 0);
        }