Skip to content

Commit

Permalink
Read System.Text.Json options
Browse files Browse the repository at this point in the history
  • Loading branch information
sindrekroknes committed Jan 27, 2020
1 parent 8c0bf76 commit 50bd47e
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,14 @@ public async Task<TSettings> CreateSettingsAsync(AssemblyLoader.AssemblyLoader a
JsonSerializerSettings serializerSettings;
try
{
var mvcJsonOptions = serviceProvider?.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>();
serializerSettings = mvcJsonOptions?.Value?.SerializerSettings;
if (mvcOptions.OutputFormatters.Any(f => f.GetType() == typeof(Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter)))
serializerSettings = serviceProvider?.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value.SerializerSettings;
else
serializerSettings = AspNetCoreOpenApiDocumentGenerator.GetSystemTextJsonSettings(serviceProvider);
}
catch
{
serializerSettings = AspNetCoreOpenApiDocumentGenerator.GetSystemTextJsonSettings();
serializerSettings = AspNetCoreOpenApiDocumentGenerator.GetSystemTextJsonSettings(serviceProvider);
}
#else
var mvcJsonOptions = serviceProvider?.GetRequiredService<IOptions<MvcJsonOptions>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Namotion.Reflection;
Expand Down Expand Up @@ -46,10 +47,29 @@ public async Task<OpenApiDocument> GenerateAsync(object serviceProvider)
{
var typedServiceProvider = (IServiceProvider)serviceProvider;

var mvcOptions = typedServiceProvider.GetRequiredService<IOptions<MvcOptions>>();
var settings = GetJsonSerializerSettings(typedServiceProvider) ?? GetSystemTextJsonSettings();
var mvcOptions = typedServiceProvider.GetRequiredService<IOptions<MvcOptions>>().Value;

Settings.ApplySettings(settings, mvcOptions.Value);
JsonSerializerSettings settings;
#if NETCOREAPP3_0
try
{
// Check for NewtonsoftJsonOutputFormatter, throws when Microsoft.AspNetCore.Mvc.NewtonsoftJson is not referenced
// Default to System.Text.Json when NewtonsoftJson is not found
if (mvcOptions.OutputFormatters.Any(f => f.GetType() == typeof(NewtonsoftJsonOutputFormatter)))
settings = GetJsonSerializerSettings(typedServiceProvider);
else
settings = GetSystemTextJsonSettings(typedServiceProvider);
}
catch
{
settings = GetSystemTextJsonSettings(typedServiceProvider);
}

#else
settings = GetJsonSerializerSettings(typedServiceProvider);
#endif

Settings.ApplySettings(settings, mvcOptions);

var apiDescriptionGroupCollectionProvider = typedServiceProvider.GetRequiredService<IApiDescriptionGroupCollectionProvider>();
return await GenerateAsync(apiDescriptionGroupCollectionProvider.ApiDescriptionGroups);
Expand All @@ -60,32 +80,11 @@ public async Task<OpenApiDocument> GenerateAsync(object serviceProvider)
/// <returns>The settings.</returns>
public static JsonSerializerSettings GetJsonSerializerSettings(IServiceProvider serviceProvider)
{
dynamic options = null;
try
{
#if NETCOREAPP3_0
options = new Func<dynamic>(() => serviceProvider?.GetRequiredService(typeof(IOptions<MvcNewtonsoftJsonOptions>)) as dynamic)();
return serviceProvider?.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value.SerializerSettings;
#else
options = new Func<dynamic>(() => serviceProvider?.GetRequiredService(typeof(IOptions<MvcJsonOptions>)) as dynamic)();
return serviceProvider?.GetRequiredService<IOptions<MvcJsonOptions>>().Value.SerializerSettings;
#endif
}
catch
{
try
{
// Try load ASP.NET Core 3 options
var optionsAssembly = Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Mvc.NewtonsoftJson"));
var optionsType = typeof(IOptions<>).MakeGenericType(optionsAssembly.GetType("Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions", true));
options = serviceProvider?.GetService(optionsType) as dynamic;
}
catch
{
// Newtonsoft.JSON not available, see GetSystemTextJsonSettings()
return null;
}
}

return (JsonSerializerSettings)options?.Value?.SerializerSettings;
}

/// <summary>Generates a Swagger specification for the given <see cref="ApiDescriptionGroupCollection"/>.</summary>
Expand Down Expand Up @@ -127,15 +126,29 @@ public async Task<OpenApiDocument> GenerateAsync(ApiDescriptionGroupCollection a

/// <summary>Gets the default serializer settings representing System.Text.Json.</summary>
/// <returns>The settings.</returns>
public static JsonSerializerSettings GetSystemTextJsonSettings()
public static JsonSerializerSettings GetSystemTextJsonSettings(IServiceProvider serviceProvider)
{
// If the ASP.NET Core website does not use Newtonsoft.JSON we need to provide a
// contract resolver which reflects best the System.Text.Json behavior.
// See https://github.com/RicoSuter/NSwag/issues/2243
return new JsonSerializerSettings
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};

#if NETCOREAPP3_0
if (serviceProvider == null) return settings;
var jsonOptions = serviceProvider.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions;

// StringEnumConverter
if (jsonOptions.Converters.Any(c => c.GetType() == typeof(System.Text.Json.Serialization.JsonStringEnumConverter)))
settings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());

if (jsonOptions.PropertyNamingPolicy == null)
// PascalCase
settings.ContractResolver = new DefaultContractResolver();
#endif
return settings;
}

private List<Type> GenerateForControllers(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.6;net451;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard1.6;net451;netstandard2.0;netcoreapp3.0</TargetFrameworks>
<Description>NSwag: The OpenAPI/Swagger API toolchain for .NET and TypeScript</Description>
<Version>13.2.2</Version>
<PackageTags>Swagger Documentation AspNetCore</PackageTags>
Expand Down Expand Up @@ -31,11 +31,12 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="1.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="1.0.3" />
</ItemGroup>
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
<PackageReference Include="Microsoft.AspNetCore.App" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
</ItemGroup>-->
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" >
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
Expand Down

0 comments on commit 50bd47e

Please sign in to comment.