public HttpResponseMessage GetApiSpecification()
        {
            string spec = "";

            var queryStringParams = Request.GetQueryNameValuePairs().ToList();
            var param1            = queryStringParams.FirstOrDefault(kv => kv.Key.Equals("openapi", StringComparison.CurrentCultureIgnoreCase)).Value;

            if (param1 == "2.0")
            {
                spec = OpenApiSpecification.GetSpecAsV2();
            }
            else
            {
                spec = OpenApiSpecification.GetSpecAsV3();
            }
            return(new HttpResponseMessage {
                Content = new StringContent(spec)
            });
        }
        private void AddSchemaDefinitionsToModels(OpenApiSpecification spec, JObject model)
        {
            var definitionsNode = model["definitions"];

            if (definitionsNode != null)
            {
                foreach (var p in definitionsNode.Children().Where(x => x.Type == JTokenType.Property && x.HasValues).Cast <JProperty>().ToArray())
                {
                    if (p == null)
                    {
                        continue;
                    }

                    if (p.Name != null && !spec.Component.ModelDefinitions.ContainsKey(p.Name))
                    {
                        var jo = p.Value.ToObject <JObject>();
                        jo.AddFirst(new JProperty("title", p.Name));
                        spec.Component.ModelDefinitions.Add(p.Name, jo);
                        AddSchemaDefinitionsToModels(spec, jo);
                    }
                }
                model.Remove("definitions");
            }
        }
        /// <summary>
        /// This operation generates the specification upon the openApiSpecification variable.
        /// </summary>
        private void GenerateSpecification()
        {
            openApiSpecification = new OpenApiSpecification
            {
                Info = new Info
                {
                    Title          = title,
                    Version        = apiVersion,
                    TermsOfService = termsOfService,
                    Contact        = contact,
                    License        = license,
                },
                Servers      = hosts,
                Tags         = tags,
                ExternalDocs = externalDocs
            };

            // Generate documentation
            IEnumerable <OpenApiRouteMetadata> metadata = routeCacheProvider.GetCache().RetrieveMetadata <OpenApiRouteMetadata>();

            var endpoints = new Dictionary <string, Dictionary <string, Endpoint> >();

            foreach (OpenApiRouteMetadata m in metadata)
            {
                if (m == null)
                {
                    continue;
                }

                string path = m.Path;

                //OpenApi doesnt handle these special characters on the url path construction, but Nancy allows it.
                path = Regex.Replace(path, "[?:.*]", string.Empty);

                if (!endpoints.ContainsKey(path))
                {
                    endpoints[path] = new Dictionary <string, Endpoint>();
                }

                endpoints[path].Add(m.Method, m.Info);

                // add definitions
                if (openApiSpecification.Component == null)
                {
                    openApiSpecification.Component = new Component();
                }

                if (openApiSpecification.Component.ModelDefinitions == null)
                {
                    openApiSpecification.Component.ModelDefinitions = new Dictionary <string, JObject>();
                }

                foreach (string key in SchemaCache.Cache.Keys)
                {
                    if (!openApiSpecification.Component.ModelDefinitions.ContainsKey(key))
                    {
                        var model = SchemaCache.Cache[key].DeepClone() as JObject;
                        openApiSpecification.Component.ModelDefinitions.Add(key, model);
                        AddSchemaDefinitionsToModels(openApiSpecification, model);
                    }
                }
            }

            openApiSpecification.PathInfos = endpoints;
        }
        /// <summary>
        /// This operation generates the specification upon the openApiSpecification variable.
        /// </summary>
        private void GenerateSpecification()
        {
            openApiSpecification = new OpenApiSpecification
            {
                Info = new Info
                {
                    Title          = title,
                    Version        = apiVersion,
                    TermsOfService = termsOfService,
                    Contact        = contact,
                    License        = license,
                },
                Servers      = hosts,
                Tags         = tags,
                ExternalDocs = externalDocs
            };

            // Generate documentation
            IEnumerable <OpenApiRouteMetadata> metadata = routeCacheProvider.GetCache().RetrieveMetadata <OpenApiRouteMetadata>();

            var endpoints = new Dictionary <string, Dictionary <string, Endpoint> >();

            foreach (OpenApiRouteMetadata m in metadata)
            {
                if (m is null)
                {
                    continue;
                }

                string path = m.Path;

                //OpenApi doesnt handle these special characters on the url path construction, but Nancy allows it.
                path = Regex.Replace(path, "[?:.*]", string.Empty);

                if (!endpoints.ContainsKey(path))
                {
                    endpoints[path] = new Dictionary <string, Endpoint>();
                }

                endpoints[path].Add(m.Method, m.Info);

                // add component definitions
                if (openApiSpecification.Component is null)
                {
                    openApiSpecification.Component = new Component();

                    if (openApiSpecification.Component.ModelDefinitions is null)
                    {
                        openApiSpecification.Component.ModelDefinitions = new Dictionary <string, NJsonSchema.JsonSchema4>();
                    }
                }

                //Components added here from Cache
                foreach (string key in SchemaCache.ComponentCache.Keys)
                {
                    if (openApiSpecification.Component.ModelDefinitions.ContainsKey(key))
                    {
                        continue;
                    }

                    openApiSpecification.Component.ModelDefinitions.Add(key, SchemaCache.ComponentCache[key]);
                }

                //Security Schemes Added here from Cache
                foreach (string key in SchemaCache.SecurityCache.Keys)
                {
                    //Since we could have all unsecured components, the Security Scheme is optional.
                    if (openApiSpecification.Component.SecuritySchemes is null)
                    {
                        openApiSpecification.Component.SecuritySchemes = new Dictionary <string, SecurityScheme>();
                    }

                    if (openApiSpecification.Component.SecuritySchemes.ContainsKey(key))
                    {
                        continue;
                    }

                    openApiSpecification.Component.SecuritySchemes.Add(key, SchemaCache.SecurityCache[key]);
                }

                //Security Requirements from the list defined by endpoint.
                if (m.Info.Security is List <Model.Security> list)
                {
                    foreach (var sec in list)
                    {
                        if (openApiSpecification.Security is null)
                        {
                            openApiSpecification.Security = new List <Model.Security>();
                        }

                        if (openApiSpecification.Security.Contains(sec))
                        {
                            continue;
                        }

                        openApiSpecification.Security.Add(sec);
                    }
                }
                else
                {
                    //If no Security was defined on each operation we assign nothing for now.
                    m.Info.Security = new List <Model.Security>();
                }
            }

            openApiSpecification.PathInfos = endpoints;
        }