diff --git a/docs/usage/openapi.md b/docs/usage/openapi.md index 43d32d8c8e..414a53bbb2 100644 --- a/docs/usage/openapi.md +++ b/docs/usage/openapi.md @@ -52,7 +52,7 @@ app.UseSwagger(options => options.RouteTemplate = "api-docs/{documentName}/swagg Instead, always call `UseSwagger()` *without parameters*. To change the route template, use the code below: ```c# -builder.Services.Configure(options => options.RouteTemplate = "api-docs/{documentName}/swagger.yaml"); +builder.Services.Configure(options => options.RouteTemplate = "/api-docs/{documentName}/swagger.yaml"); ``` If you want to inject dependencies to set the route template, use: @@ -62,7 +62,7 @@ builder.Services.AddOptions().Configure((optio { var webHostEnvironment = serviceProvider.GetRequiredService(); string appName = webHostEnvironment.ApplicationName; - options.RouteTemplate = $"api-docs/{{documentName}}/{appName}-swagger.yaml"; + options.RouteTemplate = $"/api-docs/{{documentName}}/{appName}-swagger.yaml"; }); ``` diff --git a/package-versions.props b/package-versions.props index 33447163ef..9d9b1cf595 100644 --- a/package-versions.props +++ b/package-versions.props @@ -4,7 +4,7 @@ 4.1.0 0.4.1 2.14.1 - 6.5.0 + 6.6.1 13.0.3 diff --git a/src/JsonApiDotNetCore.OpenApi/OpenApiDescriptionLinkProvider.cs b/src/JsonApiDotNetCore.OpenApi/OpenApiDescriptionLinkProvider.cs index cad1abb17b..5a469875e3 100644 --- a/src/JsonApiDotNetCore.OpenApi/OpenApiDescriptionLinkProvider.cs +++ b/src/JsonApiDotNetCore.OpenApi/OpenApiDescriptionLinkProvider.cs @@ -33,7 +33,7 @@ public OpenApiDescriptionLinkProvider(IOptionsMonitor s string latestVersionDocumentName = swaggerGeneratorOptions.SwaggerDocs.Last().Key; SwaggerOptions swaggerOptions = _swaggerOptionsMonitor.CurrentValue; - return swaggerOptions.RouteTemplate.Replace("{documentName}", latestVersionDocumentName).Replace("{json|yaml}", "json"); + return swaggerOptions.RouteTemplate.Replace("{documentName}", latestVersionDocumentName).Replace("{extension:regex(^(json|ya?ml)$)}", "json"); } return null; diff --git a/src/JsonApiDotNetCore.OpenApi/SchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SchemaGenerator.cs deleted file mode 100644 index 7bc287fe95..0000000000 --- a/src/JsonApiDotNetCore.OpenApi/SchemaGenerator.cs +++ /dev/null @@ -1,518 +0,0 @@ -// This file is a copy of https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs -// It was patched to fix broken inheritance using allOf. Changed code is marked with PATCH-START/PATCH-END comments. - -// PATCH-START -#nullable disable -#pragma warning disable -// PATCH-END - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Text.Json; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApiExplorer; -using Microsoft.OpenApi.Models; - -// PATCH-START -namespace Swashbuckle.AspNetCore.SwaggerGen.Patched -//namespace Swashbuckle.AspNetCore.SwaggerGen -// PATCH-END -{ - public class SchemaGenerator : ISchemaGenerator - { - private readonly SchemaGeneratorOptions _generatorOptions; - private readonly ISerializerDataContractResolver _serializerDataContractResolver; - - public SchemaGenerator(SchemaGeneratorOptions generatorOptions, ISerializerDataContractResolver serializerDataContractResolver) - { - _generatorOptions = generatorOptions; - _serializerDataContractResolver = serializerDataContractResolver; - } - - public OpenApiSchema GenerateSchema( - Type modelType, - SchemaRepository schemaRepository, - MemberInfo memberInfo = null, - ParameterInfo parameterInfo = null, - ApiParameterRouteInfo routeInfo = null) - { - if (memberInfo != null) - return GenerateSchemaForMember(modelType, schemaRepository, memberInfo); - - if (parameterInfo != null) - return GenerateSchemaForParameter(modelType, schemaRepository, parameterInfo, routeInfo); - - return GenerateSchemaForType(modelType, schemaRepository); - } - - private OpenApiSchema GenerateSchemaForMember( - Type modelType, - SchemaRepository schemaRepository, - MemberInfo memberInfo, - DataProperty dataProperty = null) - { - var dataContract = GetDataContractFor(modelType); - - var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts) - ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts) - : GenerateConcreteSchema(dataContract, schemaRepository); - - if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null) - { - schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; - schema.Reference = null; - } - - if (schema.Reference == null) - { - var customAttributes = memberInfo.GetInlineAndMetadataAttributes(); - - // Nullable, ReadOnly & WriteOnly are only relevant for Schema "properties" (i.e. where dataProperty is non-null) - if (dataProperty != null) - { - var requiredAttribute = customAttributes.OfType().FirstOrDefault(); - schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes - ? dataProperty.IsNullable && requiredAttribute==null && !memberInfo.IsNonNullableReferenceType() - : dataProperty.IsNullable && requiredAttribute==null; - - schema.ReadOnly = dataProperty.IsReadOnly; - schema.WriteOnly = dataProperty.IsWriteOnly; - schema.MinLength = modelType == typeof(string) && requiredAttribute is { AllowEmptyStrings: false } ? 1 : null; - } - - var defaultValueAttribute = customAttributes.OfType().FirstOrDefault(); - if (defaultValueAttribute != null) - { - var defaultAsJson = dataContract.JsonConverter(defaultValueAttribute.Value); - schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson); - } - - var obsoleteAttribute = customAttributes.OfType().FirstOrDefault(); - if (obsoleteAttribute != null) - { - schema.Deprecated = true; - } - - // NullableAttribute behaves diffrently for Dictionaries - if (schema.AdditionalPropertiesAllowed && modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) - { - schema.AdditionalProperties.Nullable = !memberInfo.IsDictionaryValueNonNullable(); - } - - schema.ApplyValidationAttributes(customAttributes); - - ApplyFilters(schema, modelType, schemaRepository, memberInfo: memberInfo); - } - - return schema; - } - - private OpenApiSchema GenerateSchemaForParameter( - Type modelType, - SchemaRepository schemaRepository, - ParameterInfo parameterInfo, - ApiParameterRouteInfo routeInfo) - { - var dataContract = GetDataContractFor(modelType); - - var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts) - ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts) - : GenerateConcreteSchema(dataContract, schemaRepository); - - if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null) - { - schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; - schema.Reference = null; - } - - if (schema.Reference == null) - { - var customAttributes = parameterInfo.GetCustomAttributes(); - - var defaultValue = parameterInfo.HasDefaultValue - ? parameterInfo.DefaultValue - : customAttributes.OfType().FirstOrDefault()?.Value; - - if (defaultValue != null) - { - var defaultAsJson = dataContract.JsonConverter(defaultValue); - schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson); - } - - schema.ApplyValidationAttributes(customAttributes); - if (routeInfo != null) - { - schema.ApplyRouteConstraints(routeInfo); - } - - ApplyFilters(schema, modelType, schemaRepository, parameterInfo: parameterInfo); - } - - return schema; - } - - private OpenApiSchema GenerateSchemaForType(Type modelType, SchemaRepository schemaRepository) - { - var dataContract = GetDataContractFor(modelType); - - var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts) - ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts) - : GenerateConcreteSchema(dataContract, schemaRepository); - - if (schema.Reference == null) - { - ApplyFilters(schema, modelType, schemaRepository); - } - - return schema; - } - - private DataContract GetDataContractFor(Type modelType) - { - var effectiveType = Nullable.GetUnderlyingType(modelType) ?? modelType; - return _serializerDataContractResolver.GetDataContractForType(effectiveType); - } - - private bool IsBaseTypeWithKnownTypesDefined(DataContract dataContract, out IEnumerable knownTypesDataContracts) - { - knownTypesDataContracts = null; - - if (dataContract.DataType != DataType.Object) return false; - - var subTypes = _generatorOptions.SubTypesSelector(dataContract.UnderlyingType); - - if (!subTypes.Any()) return false; - - var knownTypes = !dataContract.UnderlyingType.IsAbstract - ? new[] { dataContract.UnderlyingType }.Union(subTypes) - : subTypes; - - knownTypesDataContracts = knownTypes.Select(knownType => GetDataContractFor(knownType)); - return true; - } - - private OpenApiSchema GeneratePolymorphicSchema( - DataContract dataContract, - SchemaRepository schemaRepository, - IEnumerable knownTypesDataContracts) - { - return new OpenApiSchema - { - OneOf = knownTypesDataContracts - .Select(allowedTypeDataContract => GenerateConcreteSchema(allowedTypeDataContract, schemaRepository)) - .ToList() - }; - } - - private OpenApiSchema GenerateConcreteSchema(DataContract dataContract, SchemaRepository schemaRepository) - { - if (TryGetCustomTypeMapping(dataContract.UnderlyingType, out Func customSchemaFactory)) - { - return customSchemaFactory(); - } - - if (dataContract.UnderlyingType.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult))) - { - return new OpenApiSchema { Type = "string", Format = "binary" }; - } - - Func schemaFactory; - bool returnAsReference; - - switch (dataContract.DataType) - { - case DataType.Boolean: - case DataType.Integer: - case DataType.Number: - case DataType.String: - { - schemaFactory = () => CreatePrimitiveSchema(dataContract); - returnAsReference = dataContract.UnderlyingType.IsEnum && !_generatorOptions.UseInlineDefinitionsForEnums; - break; - } - - case DataType.Array: - { - schemaFactory = () => CreateArraySchema(dataContract, schemaRepository); - returnAsReference = dataContract.UnderlyingType == dataContract.ArrayItemType; - break; - } - - case DataType.Dictionary: - { - schemaFactory = () => CreateDictionarySchema(dataContract, schemaRepository); - returnAsReference = dataContract.UnderlyingType == dataContract.DictionaryValueType; - break; - } - - case DataType.Object: - { - schemaFactory = () => CreateObjectSchema(dataContract, schemaRepository); - returnAsReference = true; - break; - } - - default: - { - schemaFactory = () => new OpenApiSchema(); - returnAsReference = false; - break; - } - } - - return returnAsReference - ? GenerateReferencedSchema(dataContract, schemaRepository, schemaFactory) - : schemaFactory(); - } - - private bool TryGetCustomTypeMapping(Type modelType, out Func schemaFactory) - { - return _generatorOptions.CustomTypeMappings.TryGetValue(modelType, out schemaFactory) - || (modelType.IsConstructedGenericType && _generatorOptions.CustomTypeMappings.TryGetValue(modelType.GetGenericTypeDefinition(), out schemaFactory)); - } - - private OpenApiSchema CreatePrimitiveSchema(DataContract dataContract) - { - var schema = new OpenApiSchema - { - Type = dataContract.DataType.ToString().ToLower(CultureInfo.InvariantCulture), - Format = dataContract.DataFormat - }; - - // For backcompat only - EnumValues is obsolete - if (dataContract.EnumValues != null) - { - schema.Enum = dataContract.EnumValues - .Select(value => JsonSerializer.Serialize(value)) - .Distinct() - .Select(valueAsJson => OpenApiAnyFactory.CreateFromJson(valueAsJson)) - .ToList(); - - return schema; - } - - if (dataContract.UnderlyingType.IsEnum) - { - schema.Enum = dataContract.UnderlyingType.GetEnumValues() - .Cast() - .Select(value => dataContract.JsonConverter(value)) - .Distinct() - .Select(valueAsJson => OpenApiAnyFactory.CreateFromJson(valueAsJson)) - .ToList(); - } - - return schema; - } - - private OpenApiSchema CreateArraySchema(DataContract dataContract, SchemaRepository schemaRepository) - { - var hasUniqueItems = dataContract.UnderlyingType.IsConstructedFrom(typeof(ISet<>), out _) - || dataContract.UnderlyingType.IsConstructedFrom(typeof(KeyedCollection<,>), out _); - - return new OpenApiSchema - { - Type = "array", - Items = GenerateSchema(dataContract.ArrayItemType, schemaRepository), - UniqueItems = hasUniqueItems ? (bool?)true : null - }; - } - - private OpenApiSchema CreateDictionarySchema(DataContract dataContract, SchemaRepository schemaRepository) - { - if (dataContract.DictionaryKeys != null) - { - // This is a special case where the set of key values is known (e.g. if the key type is an enum) - return new OpenApiSchema - { - Type = "object", - Properties = dataContract.DictionaryKeys.ToDictionary( - name => name, - name => GenerateSchema(dataContract.DictionaryValueType, schemaRepository)), - AdditionalPropertiesAllowed = false, - }; - } - else - { - return new OpenApiSchema - { - Type = "object", - AdditionalPropertiesAllowed = true, - AdditionalProperties = GenerateSchema(dataContract.DictionaryValueType, schemaRepository) - }; - } - } - - private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository) - { - var schema = new OpenApiSchema - { - Type = "object", - Properties = new Dictionary(), - Required = new SortedSet(), - AdditionalPropertiesAllowed = false - }; - - // PATCH-START - OpenApiSchema root = schema; - // PATCH-END - - var applicableDataProperties = dataContract.ObjectProperties; - - if (_generatorOptions.UseAllOfForInheritance || _generatorOptions.UseOneOfForPolymorphism) - { - if (IsKnownSubType(dataContract, out var baseTypeDataContract)) - { - var baseTypeSchema = GenerateConcreteSchema(baseTypeDataContract, schemaRepository); - - // PATCH-START - root = new OpenApiSchema(); - root.AllOf.Add(baseTypeSchema); - //schema.AllOf.Add(baseTypeSchema); - // PATCH-END - - applicableDataProperties = applicableDataProperties - .Where(dataProperty => dataProperty.MemberInfo.DeclaringType == dataContract.UnderlyingType); - } - - if (IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts)) - { - foreach (var knownTypeDataContract in knownTypesDataContracts) - { - // Ensure schema is generated for all known types - GenerateConcreteSchema(knownTypeDataContract, schemaRepository); - } - - if (TryGetDiscriminatorFor(dataContract, schemaRepository, knownTypesDataContracts, out var discriminator)) - { - schema.Properties.Add(discriminator.PropertyName, new OpenApiSchema { Type = "string" }); - schema.Required.Add(discriminator.PropertyName); - schema.Discriminator = discriminator; - } - } - } - - foreach (var dataProperty in applicableDataProperties) - { - var customAttributes = dataProperty.MemberInfo?.GetInlineAndMetadataAttributes() ?? Enumerable.Empty(); - - if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType().Any()) - continue; - - schema.Properties[dataProperty.Name] = (dataProperty.MemberInfo != null) - ? GenerateSchemaForMember(dataProperty.MemberType, schemaRepository, dataProperty.MemberInfo, dataProperty) - : GenerateSchemaForType(dataProperty.MemberType, schemaRepository); - - if ((dataProperty.IsRequired || customAttributes.OfType().Any()) - && !schema.Required.Contains(dataProperty.Name)) - { - schema.Required.Add(dataProperty.Name); - } - } - - if (dataContract.ObjectExtensionDataType != null) - { - schema.AdditionalPropertiesAllowed = true; - schema.AdditionalProperties = GenerateSchema(dataContract.ObjectExtensionDataType, schemaRepository); - } - - // PATCH-START - if (root != schema) - { - root.AllOf.Add(schema); - } - - return root; - //return schema; - // PATCH-END - } - - private bool IsKnownSubType(DataContract dataContract, out DataContract baseTypeDataContract) - { - baseTypeDataContract = null; - - var baseType = dataContract.UnderlyingType.BaseType; - - if (baseType == null || baseType == typeof(object) || !_generatorOptions.SubTypesSelector(baseType).Contains(dataContract.UnderlyingType)) - return false; - - baseTypeDataContract = GetDataContractFor(baseType); - return true; - } - - private bool TryGetDiscriminatorFor( - DataContract dataContract, - SchemaRepository schemaRepository, - IEnumerable knownTypesDataContracts, - out OpenApiDiscriminator discriminator) - { - discriminator = null; - - var discriminatorName = _generatorOptions.DiscriminatorNameSelector(dataContract.UnderlyingType) - ?? dataContract.ObjectTypeNameProperty; - - if (discriminatorName == null) return false; - - discriminator = new OpenApiDiscriminator - { - PropertyName = discriminatorName - }; - - foreach (var knownTypeDataContract in knownTypesDataContracts) - { - var discriminatorValue = _generatorOptions.DiscriminatorValueSelector(knownTypeDataContract.UnderlyingType) - ?? knownTypeDataContract.ObjectTypeNameValue; - - if (discriminatorValue == null) continue; - - discriminator.Mapping.Add(discriminatorValue, GenerateConcreteSchema(knownTypeDataContract, schemaRepository).Reference.ReferenceV3); - } - - return true; - } - - private OpenApiSchema GenerateReferencedSchema( - DataContract dataContract, - SchemaRepository schemaRepository, - Func definitionFactory) - { - if (schemaRepository.TryLookupByType(dataContract.UnderlyingType, out OpenApiSchema referenceSchema)) - return referenceSchema; - - var schemaId = _generatorOptions.SchemaIdSelector(dataContract.UnderlyingType); - - schemaRepository.RegisterType(dataContract.UnderlyingType, schemaId); - - var schema = definitionFactory(); - ApplyFilters(schema, dataContract.UnderlyingType, schemaRepository); - - return schemaRepository.AddDefinition(schemaId, schema); - } - - private void ApplyFilters( - OpenApiSchema schema, - Type type, - SchemaRepository schemaRepository, - MemberInfo memberInfo = null, - ParameterInfo parameterInfo = null) - { - var filterContext = new SchemaFilterContext( - type: type, - schemaGenerator: this, - schemaRepository: schemaRepository, - memberInfo: memberInfo, - parameterInfo: parameterInfo); - - foreach (var filter in _generatorOptions.SchemaFilters) - { - filter.Apply(schema, filterContext); - } - } - } -} diff --git a/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs index 8168b56e04..7df1945c66 100644 --- a/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/DocumentSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/DocumentSchemaGenerator.cs index 02d5f2098e..cc9376a353 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/DocumentSchemaGenerator.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/DocumentSchemaGenerator.cs @@ -4,7 +4,6 @@ using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi.SwaggerComponents; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiSchemaGenerator.cs index aca57a94cf..af4d0167ef 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiSchemaGenerator.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiSchemaGenerator.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi.SwaggerComponents; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs index dbfe667691..27282938cf 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs @@ -3,7 +3,6 @@ using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi.SwaggerComponents; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs index fd9852d45a..284d88c78f 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs @@ -5,7 +5,6 @@ using JsonApiDotNetCore.Resources.Annotations; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi.SwaggerComponents; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceIdentifierSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceIdentifierSchemaGenerator.cs index d28fc9d60e..f17b0e0f3c 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceIdentifierSchemaGenerator.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceIdentifierSchemaGenerator.cs @@ -2,7 +2,6 @@ using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; -using SchemaGenerator = Swashbuckle.AspNetCore.SwaggerGen.Patched.SchemaGenerator; namespace JsonApiDotNetCore.OpenApi.SwaggerComponents; diff --git a/test/OpenApiKiotaEndToEndTests/Links/AlternateOpenApiRouteTests.cs b/test/OpenApiKiotaEndToEndTests/Links/AlternateOpenApiRouteTests.cs index cbec1d0e5e..3089f79230 100644 --- a/test/OpenApiKiotaEndToEndTests/Links/AlternateOpenApiRouteTests.cs +++ b/test/OpenApiKiotaEndToEndTests/Links/AlternateOpenApiRouteTests.cs @@ -24,7 +24,7 @@ public AlternateOpenApiRouteTests(IntegrationTestContext - services.Configure(options => options.RouteTemplate = "api-docs/{documentName}/swagger.yaml")); + services.Configure(options => options.RouteTemplate = "/api-docs/{documentName}/swagger.yaml")); testContext.UseController(); } @@ -50,6 +50,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert response.ShouldNotBeNull(); response.Links.ShouldNotBeNull(); - response.Links.Describedby.Should().Be("api-docs/v1/swagger.yaml"); + response.Links.Describedby.Should().Be("/api-docs/v1/swagger.yaml"); } } diff --git a/test/OpenApiKiotaEndToEndTests/QueryStrings/FilterTests.cs b/test/OpenApiKiotaEndToEndTests/QueryStrings/FilterTests.cs index 913d03ea8b..69aac23c51 100644 --- a/test/OpenApiKiotaEndToEndTests/QueryStrings/FilterTests.cs +++ b/test/OpenApiKiotaEndToEndTests/QueryStrings/FilterTests.cs @@ -140,7 +140,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => response.Meta.ShouldNotBeNull(); response.Meta.AdditionalData.ShouldContainKey("total").With(total => total.Should().Be(1)); response.Links.ShouldNotBeNull(); - response.Links.Describedby.Should().Be("swagger/v1/swagger.json"); + response.Links.Describedby.Should().Be("/swagger/v1/swagger.json"); } } @@ -166,7 +166,7 @@ public async Task Cannot_use_empty_filter() exception.ResponseStatusCode.Should().Be((int)HttpStatusCode.BadRequest); exception.Message.Should().Be($"Exception of type '{typeof(ErrorResponseDocument).FullName}' was thrown."); exception.Links.ShouldNotBeNull(); - exception.Links.Describedby.Should().Be("swagger/v1/swagger.json"); + exception.Links.Describedby.Should().Be("/swagger/v1/swagger.json"); exception.Errors.ShouldHaveCount(1); ErrorObject error = exception.Errors[0]; diff --git a/test/OpenApiNSwagClientTests/LegacyOpenApi/ResponseTests.cs b/test/OpenApiNSwagClientTests/LegacyOpenApi/ResponseTests.cs index 093779198b..fe2b44ed34 100644 --- a/test/OpenApiNSwagClientTests/LegacyOpenApi/ResponseTests.cs +++ b/test/OpenApiNSwagClientTests/LegacyOpenApi/ResponseTests.cs @@ -204,7 +204,7 @@ public async Task Getting_unknown_resource_translates_error_response() { "links": { "self": "http://localhost/api/flights/ZvuH1", - "describedby": "swagger/v1/swagger.json" + "describedby": "/swagger/v1/swagger.json" }, "errors": [ { @@ -228,7 +228,7 @@ public async Task Getting_unknown_resource_translates_error_response() exception.StatusCode.Should().Be((int)HttpStatusCode.NotFound); exception.Result.Links.ShouldNotBeNull(); exception.Result.Links.Self.Should().Be("http://localhost/api/flights/ZvuH1"); - exception.Result.Links.Describedby.Should().Be("swagger/v1/swagger.json"); + exception.Result.Links.Describedby.Should().Be("/swagger/v1/swagger.json"); exception.Result.Errors.ShouldHaveCount(1); ErrorObject? error = exception.Result.Errors.ElementAt(0); diff --git a/test/OpenApiNSwagEndToEndTests/Links/AlternateOpenApiRouteTests.cs b/test/OpenApiNSwagEndToEndTests/Links/AlternateOpenApiRouteTests.cs index 4d96310190..a99a4889a6 100644 --- a/test/OpenApiNSwagEndToEndTests/Links/AlternateOpenApiRouteTests.cs +++ b/test/OpenApiNSwagEndToEndTests/Links/AlternateOpenApiRouteTests.cs @@ -22,7 +22,7 @@ public AlternateOpenApiRouteTests(IntegrationTestContext - services.Configure(options => options.RouteTemplate = "api-docs/{documentName}/swagger.yaml")); + services.Configure(options => options.RouteTemplate = "/api-docs/{documentName}/swagger.yaml")); testContext.UseController(); } @@ -46,6 +46,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => ExcursionPrimaryResponseDocument response = await apiClient.GetExcursionAsync(excursion.StringId!, null, null); // Assert - response.Links.Describedby.Should().Be("api-docs/v1/swagger.yaml"); + response.Links.Describedby.Should().Be("/api-docs/v1/swagger.yaml"); } } diff --git a/test/OpenApiNSwagEndToEndTests/QueryStrings/FilterTests.cs b/test/OpenApiNSwagEndToEndTests/QueryStrings/FilterTests.cs index cb351910fa..44a35c746d 100644 --- a/test/OpenApiNSwagEndToEndTests/QueryStrings/FilterTests.cs +++ b/test/OpenApiNSwagEndToEndTests/QueryStrings/FilterTests.cs @@ -128,7 +128,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => response.Meta.ShouldNotBeNull(); response.Meta.ShouldContainKey("total").With(total => total.Should().Be(1)); response.Links.ShouldNotBeNull(); - response.Links.Describedby.Should().Be("swagger/v1/swagger.json"); + response.Links.Describedby.Should().Be("/swagger/v1/swagger.json"); } [Fact] @@ -151,7 +151,7 @@ public async Task Cannot_use_empty_filter() exception.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); exception.Message.Should().Be("HTTP 400: The query string is invalid."); exception.Result.Links.ShouldNotBeNull(); - exception.Result.Links.Describedby.Should().Be("swagger/v1/swagger.json"); + exception.Result.Links.Describedby.Should().Be("/swagger/v1/swagger.json"); exception.Result.Errors.ShouldHaveCount(1); ErrorObject error = exception.Result.Errors.ElementAt(0); diff --git a/test/OpenApiTests/OpenApiTestContext.cs b/test/OpenApiTests/OpenApiTestContext.cs index 6522dfc4e8..c624f06f2a 100644 --- a/test/OpenApiTests/OpenApiTestContext.cs +++ b/test/OpenApiTests/OpenApiTestContext.cs @@ -26,7 +26,7 @@ internal async Task GetSwaggerDocumentAsync() private async Task CreateSwaggerDocumentAsync() { - string content = await GetAsync("swagger/v1/swagger.json"); + string content = await GetAsync("/swagger/v1/swagger.json"); JsonElement rootElement = ParseSwaggerDocument(content);