Swashbuckle.AspNetCore.Filters icon indicating copy to clipboard operation
Swashbuckle.AspNetCore.Filters copied to clipboard

How to properly wire up generic versions of AppendAuthorizeToSummaryOperationFilter<T> and SecurityRequirementsOperationFilter<T>?

Open omon77 opened this issue 1 year ago • 1 comments

Using the code from comments to wire up MyCustomAttribute which derives from AuthorizeAttribute, results in error:

InvalidOperationException: Unable to resolve service for type 'System.Func2[System.Collections.Generic.IEnumerable1[MyCustomAttribute],System.Collections.Generic.IEnumerable1[System.String]]' while attempting to activate 'Swashbuckle.AspNetCore.Filters.SecurityRequirementsOperationFilter1[MyCustomAttribute]'.

services.AddSwaggerGen(c =>
        {
            c.EnableAnnotations();
            
            // Adds "(Auth)" to the summary so that you can see which endpoints have Authorization
            // or use the generic method, e.g. c.OperationFilter<AppendAuthorizeToSummaryOperationFilter<MyCustomAttribute>>();
            c.OperationFilter<AppendAuthorizeToSummaryOperationFilter<MyCustomAttribute>>();

            // add Security information to each operation for OAuth2
            // or use the generic method, e.g. c.OperationFilter<SecurityRequirementsOperationFilter<MyCustomAttribute>>();
            c.OperationFilter<SecurityRequirementsOperationFilter<MyCustomAttribute>>();

        });

MyCustomAttribute:

public class MyCustomAttribute: AuthorizeAttribute 
{
    /// <summary>
    /// Initializes a new instance of the <see cref="MyCustomAttribute"/> class.
    /// </summary>
    public MyCustomAttribute() : base()
    { }
}

Raw exception details:

System.InvalidOperationException: Unable to resolve service for type 'System.Func`2[System.Collections.Generic.IEnumerable`1[MyCustomAttribute],System.Collections.Generic.IEnumerable`1[System.String]]' while attempting to activate 'Swashbuckle.AspNetCore.Filters.SecurityRequirementsOperationFilter`1[MyCustomAttribute]'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions.CreateFilter[TFilter](FilterDescriptor filterDescriptor)
   at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions.<>c__DisplayClass4_0.<Configure>b__2(FilterDescriptor filterDescriptor)
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions.Configure(SwaggerGeneratorOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.UnnamedOptionsManager`1.get_Value()
   at Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.<>c.<AddSwaggerGen>b__0_1(IServiceProvider s)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   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.VisitDisposeCache(ServiceCallSite transientCallSite, 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__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at lambda_method1(Closure, Object, HttpContext, IServiceProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

omon77 avatar Jan 16 '24 16:01 omon77

Have a look at https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters/blob/master/src/Swashbuckle.AspNetCore.Filters/AppendAuthorizeToSummary/AppendAuthorizeToSummaryOperationFilter.cs which is where I'm using it.

It looks like I chose to "favour composition over inheritance" when I wrote it 6 years ago.

mattfrear avatar Jan 19 '24 02:01 mattfrear