Hi
I'm using Swashbuckle for API generation with gRPC HTTP endpoints. To do this I've overridden Swashbuckle's IContractResolver.
In recent versions of Swashbuckle there have been API breaking changes here. See https://github.com/grpc/grpc-dotnet/issues/167#issuecomment-727814053
I've updated my library to use the latest changes in Swashbuckle.AspNetCore.SwaggerGen - https://github.com/aspnet/AspLabs/pull/319 - but I noticed in the latest source code that ISerializerDataContractResolver was renamed again to ISerializerBehavior.
My ask is that you try to find a stable API for Swashbuckle.AspNetCore.SwaggerGen. Thanks 馃槃
Totally fair ask - and you're probably not going to be happy about some of the further changes I'm exploring for that area of the code 馃槄. I've been a little more "dynamic" about refactoring that particular abstraction because a) it's an area of the code that I'm constantly battling with and believe there has to be a simpler way and b) it's super low-level and not really something I'd consider as part of the "public interface". Not for the faint-hearted - something that should come with an "extend at your own risk" warning.
But of course, now that you've made me aware of an important project that does exactly that, I'll definitely strive for a stable API. Based on the current refactorings I'm looking at, perhaps we could agree on one final "breaking" change before locking it in for the longer term. I'll ping you with the MR when it's ready.
Had an issue regarding this, though fully unrelated to the gRPC lib, and wish just to document it here.
We observed the following error in our ASP .NET Core 3.1 project:
(click to expand)
Could not load type 'Swashbuckle.AspNetCore.SwaggerGen.IDataContractResolver' from assembly 'Swashbuckle.AspNetCore.SwaggerGen, Version=5.6.3.0, Culture=neutral, PublicKeyToken=d84d99fb0135530a'.
Application startup exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load type 'Swashbuckle.AspNetCore.SwaggerGen.IDataContractResolver' from assembly 'Swashbuckle.AspNetCore.SwaggerGen, Version=5.6.3.0, Culture=neutral, PublicKeyToken=d84d99fb0135530a'.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeAssembly.get_DefinedTypes()
at Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPart.get_Types()
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFeatureProvider.PopulateFeature(IEnumerable`1 parts, ControllerFeature feature)
at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateFeature[TFeature](TFeature feature)
at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetControllerTypes()
at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetDescriptors()
at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection()
at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.Initialize()
at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.GetChangeToken()
at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.<>c__DisplayClass11_0.<Subscribe>b__0()
at Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration`1..ctor(Func`1 changeTokenProducer, Action`1 changeTokenConsumer, TState state)
at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)
at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.Subscribe()
at Microsoft.AspNetCore.Mvc.Routing.ControllerActionEndpointDataSource..ctor(IActionDescriptorCollectionProvider actions, ActionEndpointFactory endpointFactory)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.MapControllers(IEndpointRouteBuilder endpoints)
at OUR_PROJECT_NAME.Startup.<>c.<Configure>b__5_0(IEndpointRouteBuilder c) in /src/src/OUR_PROJECT_NAME/Startup.cs:line 78
at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
at OUR_PROJECT_NAME.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in /src/src/OUR_PROJECT_NAME/Startup.cs:line 76
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()
The issue we had was that we had a dependency on an internal package of our that referenced some Swashbuckle.AspNetCore.* packages, and one being Swashbuckle.AspNetCore.Newtonsoft, all with version 5.4.1. We then had a dependency on this internal package, but also an explicit reference to Swashbuckle.AspNetCore with version 5.6.3.
Just to visualize, our .csproj had something like this:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- snip -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OUR_INTERNAL_PACKAGE" Version="1.1.449" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
</ItemGroup>
</Project>
As the Swashbuckle.AspNetCore NuGet package does not reference Swashbuckle.AspNetCore.Newtonsoft but the OUT_INTERNAL_PACKAGE does, NuGet then resolved the following versions:

The solution here was just to force the Swashbuckle.AspNetCore.Newtonsoft package up to v5.6.3 by simply adding it to the projects .csproj file as well.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- snip -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OUR_INTERNAL_PACKAGE" Version="1.1.449" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
+ <PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.6.3" />
</ItemGroup>
</Project>
Not the most pleasant of debugging sessions I've experienced, so hopefully this comment could help someone else that experiences the same issue.
@JamesNK - I've maintained a backwards compatible API (vs 5.6.3) for the upcoming 6.0.0 release.
However, the current design and related abstractions are becoming increasingly unworkable as new features are added. Once 6.0.0 is out, I want to tackle this with some fundamental design changes. In doing so, I'll seek to minimize disruption by maintaining dual implementations with old APIs marked obsolete for a single major version cycle.
Hi @domaindrivendev I am seeing the same issue with :
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.0.2" />
as well. System.AggregateException : One or more errors occurred. (Could not load type 'Swashbuckle.AspNetCore.SwaggerGen.IDataContractResolver' from assembly 'Swashbuckle.AspNetCore.SwaggerGen, Version=6.0.2.0, Culture=neutral, PublicKeyToken=d84d99fb0135530a'.)
Any suggestions?
I saw from above comments it should have been resolved in 6.0.0?
I will try to update the Swashbuckle.AspNetCore.Newtonsoft and see if that fixes the issue.
Regards,
Vikas
Had an issue regarding this, though fully unrelated to the gRPC lib, and wish just to document it here.
We observed the following error in our ASP .NET Core 3.1 project:
(click to expand)
Could not load type 'Swashbuckle.AspNetCore.SwaggerGen.IDataContractResolver' from assembly 'Swashbuckle.AspNetCore.SwaggerGen, Version=5.6.3.0, Culture=neutral, PublicKeyToken=d84d99fb0135530a'.
The issue we had was that we had a dependency on an internal package of our that referenced someSwashbuckle.AspNetCore.*packages, and one beingSwashbuckle.AspNetCore.Newtonsoft, all with version5.4.1. We then had a dependency on this internal package, but also an explicit reference toSwashbuckle.AspNetCorewith version5.6.3.Just to visualize, our
.csprojhad something like this:<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <!-- snip --> </PropertyGroup> <ItemGroup> <PackageReference Include="OUR_INTERNAL_PACKAGE" Version="1.1.449" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> </ItemGroup> </Project>As the
Swashbuckle.AspNetCoreNuGet package does not referenceSwashbuckle.AspNetCore.Newtonsoftbut theOUT_INTERNAL_PACKAGEdoes, NuGet then resolved the following versions:
The solution here was just to force the
Swashbuckle.AspNetCore.Newtonsoftpackage up to v5.6.3 by simply adding it to the projects.csprojfile as well.<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <!-- snip --> </PropertyGroup> <ItemGroup> <PackageReference Include="OUR_INTERNAL_PACKAGE" Version="1.1.449" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> + <PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.6.3" /> </ItemGroup> </Project>Not the most pleasant of debugging sessions I've experienced, so hopefully this comment could help someone else that experiences the same issue.
Thanks @jilleJr for your detailed response. Unfortunately I saw the same issue with 6.0.2 version as well. I would not have been able to resolve this issue quickly if I had not seen your comment. The error is very misleading and until you check the code like you did, its not possible. Thanks once again!
Most helpful comment
@JamesNK - I've maintained a backwards compatible API (vs
5.6.3) for the upcoming6.0.0release.However, the current design and related abstractions are becoming increasingly unworkable as new features are added. Once
6.0.0is out, I want to tackle this with some fundamental design changes. In doing so, I'll seek to minimize disruption by maintaining dual implementations with old APIs marked obsolete for a single major version cycle.