public SwaggerDocument GetSwagger(string rootUrl, string apiVersion) { var schemaRegistry = new SchemaRegistry(_jsonSerializerSettings, _options); Info info; _apiVersions.TryGetValue(apiVersion, out info); if (info == null) { throw new UnknownApiVersion(apiVersion); } HashSet <string> operationNames = new HashSet <string>(); var apiDescriptions = GetApiDescriptionsFor(apiVersion) .Where(apiDesc => !(_options.IgnoreObsoleteActions && apiDesc.IsObsolete())); var paths = apiDescriptions .OrderBy(_options.GroupingKeySelector, _options.GroupingKeyComparer) .GroupBy(apiDesc => apiDesc.RelativePathSansQueryString()) .ToDictionary(group => "/" + group.Key, group => CreatePathItem(group, schemaRegistry, operationNames)); var rootUri = new Uri(rootUrl); var port = (!rootUri.IsDefaultPort) ? ":" + rootUri.Port : string.Empty; var controllers = apiDescriptions .GroupBy(x => x.ActionDescriptor.ControllerDescriptor) .Select(x => new { name = x.Key.ControllerName, context = new ModelFilterContext(x.Key.ControllerType, null, null) }); var tags = new List <Tag>(); foreach (var filter in _options.ModelFilters) { foreach (var c in controllers) { var model = new Schema(); filter.Apply(model, c.context); if (!string.IsNullOrEmpty(model.description) && !tags.Any(t => t.name.Equals(c.name))) { tags.Add(new Tag() { name = c.name, description = model.description }); } } } var swaggerDoc = new SwaggerDocument { info = info, host = rootUri.Host + port, basePath = (rootUri.AbsolutePath != "/") ? rootUri.AbsolutePath : null, tags = (tags.Count > 0) ? tags : null, schemes = (_options.Schemes != null) ? _options.Schemes.ToList() : new[] { rootUri.Scheme }.ToList(), paths = paths, definitions = schemaRegistry.Definitions, securityDefinitions = _options.SecurityDefinitions }; foreach (var filter in _options.DocumentFilters) { filter.Apply(swaggerDoc, schemaRegistry, _apiExplorer); } return(swaggerDoc); }
private Parameter CreateParameter(string location, ApiParameterDescription paramDesc, SchemaRegistry schemaRegistry) { var parameter = new Parameter { @in = location, name = paramDesc.Name }; if (paramDesc.ParameterDescriptor == null) { parameter.type = "string"; parameter.required = true; } else { parameter.pattern = paramDesc.GetRegularExpressionAttribute()?.Pattern; parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional; parameter.description = paramDesc.Documentation; if (parameter.description == null) { parameter.description = paramDesc.GetDescriptionAttribute()?.Description; } var schema = schemaRegistry.GetOrRegister(paramDesc.ParameterDescriptor.ParameterType); if (parameter.@in == "body") { parameter.schema = schema; } else { parameter.PopulateFrom(schema); } if (paramDesc.ParameterDescriptor.DefaultValue != null) { parameter.@default = paramDesc.ParameterDescriptor.DefaultValue; } } return(parameter); }
private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaRegistry, HashSet <string> operationNames) { var parameters = apiDesc.ParameterDescriptions .Select(paramDesc => { string location = GetParameterLocation(apiDesc, paramDesc); return(CreateParameter(location, paramDesc, schemaRegistry)); }) .ToList(); var description = apiDesc.ActionDescriptor.GetCustomAttributes <SwaggerDescriptionAttribute>() .FirstOrDefault(); var responses = new Dictionary <string, Response>(); var responseType = apiDesc.ResponseType(); if (responseType == null || responseType == typeof(void)) { responses.Add("204", new Response { description = "No Content" }); } else { responses.Add("200", new Response { description = "OK", schema = schemaRegistry.GetOrRegister(responseType) }); } var operation = new Operation { tags = new[] { _options.GroupingKeySelector(apiDesc) }, operationId = this.GetUniqueOperationId(apiDesc, operationNames), description = description?.Description, summary = description?.Summary, produces = apiDesc.Produces().ToList(), consumes = apiDesc.Consumes().ToList(), parameters = parameters.Any() ? parameters : null, // parameters can be null but not empty responses = responses, }; if (apiDesc.IsObsolete()) { operation.deprecated = true; var message = apiDesc.ObsoleteMessage(); if (!string.IsNullOrEmpty(message)) { if (operation.summary == null) { operation.summary = message; } else if (operation.description == null) { operation.description = message; } } } foreach (var filter in _options.OperationFilters) { filter.Apply(operation, schemaRegistry, apiDesc); } return(operation); }
private PathItem CreatePathItem(IEnumerable <ApiDescription> apiDescriptions, SchemaRegistry schemaRegistry, HashSet <string> operationNames) { var pathItem = new PathItem(); // Group further by http method var perMethodGrouping = apiDescriptions .GroupBy(apiDesc => apiDesc.HttpMethod.Method.ToLower()); foreach (var group in perMethodGrouping) { var httpMethod = group.Key; var apiDescription = (group.Count() == 1) ? group.First() : _options.ConflictingActionsResolver(group); switch (httpMethod) { case "get": pathItem.get = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "put": pathItem.put = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "post": pathItem.post = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "delete": pathItem.delete = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "options": pathItem.options = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "head": pathItem.head = CreateOperation(apiDescription, schemaRegistry, operationNames); break; case "patch": pathItem.patch = CreateOperation(apiDescription, schemaRegistry, operationNames); break; } } return(pathItem); }
private Parameter CreateParameter(string location, ApiParameterDescription paramDesc, SchemaRegistry schemaRegistry) { var parameter = new Parameter { @in = location, name = paramDesc.Name, }; if (paramDesc.ParameterDescriptor == null) { parameter.type = "string"; parameter.required = true; } else { parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional; parameter.description = paramDesc.Documentation; if (parameter.description == null) { parameter.description = paramDesc.GetDescriptionAttribute()?.Description; } var schema = schemaRegistry.GetOrRegister(paramDesc.ParameterDescriptor.ParameterType); foreach (var attribute in paramDesc.ParameterDescriptor.GetCustomAttributes <Attribute>()) { schema.AddPattern(attribute); schema.AddRange(attribute); schema.AddLength(attribute); } if (parameter.@in == "body") { parameter.schema = schema; } else { parameter.PopulateFrom(schema); } if (paramDesc.ParameterDescriptor.DefaultValue != null) { if (parameter.@enum != null && [email protected] > 0 && _options.DescribeAllEnumsAsStrings) { parameter.@default = paramDesc.ParameterDescriptor.DefaultValue.ToString(); } else { parameter.@default = paramDesc.ParameterDescriptor.DefaultValue; } } } return(parameter); }