Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .NET 8 support #2799

Merged
merged 9 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<UseArtifactsOutput>true</UseArtifactsOutput>
<VersionPrefix>6.5.1</VersionPrefix>
<VersionPrefix>6.6.0</VersionPrefix>
<WarnOnPackingNonPackableProject>false</WarnOnPackingNonPackableProject>
</PropertyGroup>
<PropertyGroup Condition=" '$(GITHUB_ACTIONS)' != '' ">
Expand Down
3 changes: 2 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.28" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.Routing" Version="2.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
Expand All @@ -23,7 +24,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="Nswag.MSbuild" Version="13.17.0" />
<PackageVersion Include="Nswag.MSbuild" Version="14.0.7" />
<PackageVersion Include="ReportGenerator" Version="5.2.2" />
<PackageVersion Include="System.Text.Json" Version="4.6.0" />
<PackageVersion Include="xunit" Version="2.7.0" />
Expand Down
19 changes: 19 additions & 0 deletions Swashbuckle.AspNetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomDocumentSerializer", "test\WebSites\CustomDocumentSerializer\CustomDocumentSerializer.csproj", "{B6037A37-4A4F-438D-B18A-0C9D1408EAB2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "test\WebSites\WebApi\WebApi.csproj", "{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -253,6 +255,22 @@ Global
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|Any CPU.Build.0 = Release|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|x64.ActiveCfg = Release|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|x64.Build.0 = Release|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|x86.ActiveCfg = Release|Any CPU
{6EA75DA8-9B1F-468E-9425-37F01A129B0F}.Release|x86.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x64.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x64.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x86.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x86.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|Any CPU.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x64.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x64.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x86.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -295,6 +313,7 @@ Global
{3BA087DA-788C-43D6-9D8B-1EF017014A4A} = {FA1B4021-0A97-4F68-B966-148191F6AAA8}
{A0EC16BE-C520-4FCF-BB54-2D79CD255F00} = {3BA087DA-788C-43D6-9D8B-1EF017014A4A}
{B6037A37-4A4F-438D-B18A-0C9D1408EAB2} = {DB3F57FC-1472-4F03-B551-43394DA3C5EB}
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6} = {DB3F57FC-1472-4F03-B551-43394DA3C5EB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {36FC6A67-247D-4149-8EDD-79FFD1A75F51}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore;annotations</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<IsTestProject>false</IsTestProject>
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;openapi;test-first;spec-first;testing;aspnetcore;xunit</PackageTags>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;openapi;test-first;spec-first;testing;aspnetcore</PackageTags>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -34,4 +34,8 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" VersionOverride="7.0.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" VersionOverride="8.0.0" />
</ItemGroup>

</Project>
3 changes: 1 addition & 2 deletions src/Swashbuckle.AspNetCore.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -102,7 +101,7 @@ public static int Main(string[] args)
? Path.Combine(Directory.GetCurrentDirectory(), arg1)
: null;

using (Stream stream = (outputPath != null ? File.OpenWrite(outputPath) : Console.OpenStandardOutput()))
using (Stream stream = outputPath != null ? File.OpenWrite(outputPath) : Console.OpenStandardOutput())
using (var streamWriter = new FormattingStreamWriter(stream, CultureInfo.InvariantCulture))
{
IOpenApiWriter writer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<OutputType>Exe</OutputType>
<PackAsTool>true</PackAsTool>
<PackageId>Swashbuckle.AspNetCore.Cli</PackageId>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<ToolCommandName>swagger</ToolCommandName>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Description>Swagger Generator opt-in component to support Newtonsoft.Json serializer behaviors</Description>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore;newtonsoft</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand All @@ -32,4 +32,8 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" VersionOverride="7.0.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" VersionOverride="8.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore;redoc</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.ApiDescriptions;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
Expand All @@ -16,7 +15,7 @@ public static class SwaggerGenServiceCollectionExtensions
Action<SwaggerGenOptions> setupAction = null)
{
// Add Mvc convention to ensure ApiExplorer is enabled for all actions
services.Configure<MvcOptions>(c =>
services.Configure<AspNetCore.Mvc.MvcOptions>(c =>
c.Conventions.Add(new SwaggerApplicationConvention()));

// Register custom configurators that takes values from SwaggerGenOptions (i.e. high level config)
Expand All @@ -30,15 +29,10 @@ public static class SwaggerGenServiceCollectionExtensions
services.TryAddTransient(s => s.GetRequiredService<IOptions<SwaggerGeneratorOptions>>().Value);
services.TryAddTransient<ISchemaGenerator, SchemaGenerator>();
services.TryAddTransient(s => s.GetRequiredService<IOptions<SchemaGeneratorOptions>>().Value);
services.TryAddTransient<ISerializerDataContractResolver>(s =>
services.AddSingleton<JsonSerializerOptionsProvider>();
services.TryAddSingleton<ISerializerDataContractResolver>(s =>
{
#if (!NETSTANDARD2_0)
var serializerOptions = s.GetService<IOptions<JsonOptions>>()?.Value?.JsonSerializerOptions
?? new JsonSerializerOptions();
#else
var serializerOptions = new JsonSerializerOptions();
#endif

var serializerOptions = s.GetRequiredService<JsonSerializerOptionsProvider>().Options;
return new JsonSerializerDataContractResolver(serializerOptions);
});

Expand All @@ -56,5 +50,46 @@ public static class SwaggerGenServiceCollectionExtensions
{
services.Configure(setupAction);
}

private sealed class JsonSerializerOptionsProvider
{
private readonly IServiceProvider _serviceProvider;
private JsonSerializerOptions _options;

public JsonSerializerOptionsProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public JsonSerializerOptions Options => _options ??= ResolveOptions();

private JsonSerializerOptions ResolveOptions()
{
JsonSerializerOptions serializerOptions;

/*
* First try to get the options configured for MVC,
* then try to get the options configured for Minimal APIs if available,
* then try the default JsonSerializerOptions if available,
* otherwise create a new instance as a last resort as this is an expensive operation.
*/
#if !NETSTANDARD2_0
serializerOptions =
_serviceProvider.GetService<IOptions<AspNetCore.Mvc.JsonOptions>>()?.Value?.JsonSerializerOptions
#if NET8_0_OR_GREATER
?? _serviceProvider.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions
#endif
#if NET7_0_OR_GREATER
?? JsonSerializerOptions.Default;
#else
?? new JsonSerializerOptions();
#endif
#else
serializerOptions = new JsonSerializerOptions();
#endif

return serializerOptions;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@

namespace Swashbuckle.AspNetCore.SwaggerGen
{
public static class XmlCommentsTextHelper
public static partial class XmlCommentsTextHelper
{
private static Regex RefTagPattern = new Regex(@"<(see|paramref) (name|cref|langword)=""([TPF]{1}:)?(?<display>.+?)"" ?/>");
private static Regex CodeTagPattern = new Regex(@"<c>(?<display>.+?)</c>");
private static Regex MultilineCodeTagPattern = new Regex(@"<code>(?<display>.+?)</code>", RegexOptions.Singleline);
private static Regex ParaTagPattern = new Regex(@"<para>(?<display>.+?)</para>", RegexOptions.Singleline);
private static Regex HrefPattern = new(@"<see href=\""(.*)\"">(.*)<\/see>");

public static string Humanize(string text)
{
if (text == null)
Expand Down Expand Up @@ -91,33 +85,67 @@ private static string GetCommonLeadingWhitespace(string[] lines)

private static string HumanizeRefTags(this string text)
{
return RefTagPattern.Replace(text, (match) => match.Groups["display"].Value);
return RefTag().Replace(text, (match) => match.Groups["display"].Value);
}

private static string HumanizeHrefTags(this string text)
{
return HrefPattern.Replace(text, m => $"[{m.Groups[2].Value}]({m.Groups[1].Value})");
return HrefTag().Replace(text, m => $"[{m.Groups[2].Value}]({m.Groups[1].Value})");
}

private static string HumanizeCodeTags(this string text)
{
return CodeTagPattern.Replace(text, (match) => "`" + match.Groups["display"].Value + "`");
return CodeTag().Replace(text, (match) => "`" + match.Groups["display"].Value + "`");
}

private static string HumanizeMultilineCodeTags(this string text)
{
return MultilineCodeTagPattern.Replace(text, (match) => "```" + match.Groups["display"].Value + "```");
return MultilineCodeTag().Replace(text, (match) => "```" + match.Groups["display"].Value + "```");
}

private static string HumanizeParaTags(this string text)
{
return ParaTagPattern.Replace(text, (match) => "<br>" + match.Groups["display"].Value);
return ParaTag().Replace(text, (match) => "<br>" + match.Groups["display"].Value);
}

private static string DecodeXml(this string text)
{
return WebUtility.HtmlDecode(text);
}

private const string RefTagPattern = @"<(see|paramref) (name|cref|langword)=""([TPF]{1}:)?(?<display>.+?)"" ?/>";
private const string CodeTagPattern = @"<c>(?<display>.+?)</c>";
private const string MultilineCodeTagPattern = @"<code>(?<display>.+?)</code>";
private const string ParaTagPattern = @"<para>(?<display>.+?)</para>";
private const string HrefPattern = @"<see href=\""(.*)\"">(.*)<\/see>";

#if NET7_0_OR_GREATER
[GeneratedRegex(RefTagPattern)]
private static partial Regex RefTag();

[GeneratedRegex(CodeTagPattern)]
private static partial Regex CodeTag();

[GeneratedRegex(MultilineCodeTagPattern, RegexOptions.Singleline)]
private static partial Regex MultilineCodeTag();

[GeneratedRegex(ParaTagPattern, RegexOptions.Singleline)]
private static partial Regex ParaTag();

[GeneratedRegex(HrefPattern)]
private static partial Regex HrefTag();
#else
private static readonly Regex _refTag = new(RefTagPattern);
private static readonly Regex _codeTag = new(CodeTagPattern);
private static readonly Regex _multilineCodeTag = new(MultilineCodeTagPattern, RegexOptions.Singleline);
private static readonly Regex _paraTag = new(ParaTagPattern, RegexOptions.Singleline);
private static readonly Regex _hrefTag = new(HrefPattern);

private static Regex RefTag() => _refTag;
private static Regex CodeTag() => _codeTag;
private static Regex MultilineCodeTag() => _multilineCodeTag;
private static Regex ParaTag() => _paraTag;
private static Regex HrefTag() => _hrefTag;
#endif
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NoWarn>$(NoWarn);1591</NoWarn>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
<SignAssembly>true</SignAssembly>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Swashbuckle.AspNetCore/Swashbuckle.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
<PackageId>Swashbuckle.AspNetCore</PackageId>
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<Target Name="PopulateNuspec">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Xunit;
using Swashbuckle.AspNetCore.SwaggerGen;
using Xunit;

namespace Swashbuckle.AspNetCore.Annotations.Test
{
Expand Down Expand Up @@ -101,9 +102,12 @@ public void Apply_DelegatesToSpecifiedFilter_IfTypeDecoratedWithFilterAttribute(
Assert.NotEmpty(schema.Extensions);
}

private AnnotationsSchemaFilter Subject()
private static AnnotationsSchemaFilter Subject()
{
return new AnnotationsSchemaFilter(null);
// A service provider is required from .NET 8 onwards.
// See https://learn.microsoft.com/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-null-provider.
var serviceProvider = new ServiceCollection().BuildServiceProvider();
return new AnnotationsSchemaFilter(serviceProvider);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down