NSwag не распознает пользовательские атрибуты авторизации

#asp.net-core-webapi #asp.net-core-3.1 #authorize-attribute #nswag

#asp.net-core-webapi #asp.net-core-3.1 #authorize-атрибут #nswag

Вопрос:

В настоящее время возникла проблема с генерацией NSwag для пользовательского атрибута авторизации. Я был совершенно не в состоянии найти что-либо по этому вопросу в другом месте.

Я создал пользовательский атрибут для своего WebAPI и более или менее следовал шаблонам, рекомендованным здесь

 internal class AuthorizeWithPermissionAttribute : AuthorizeAttribute
{
    const string POLICY_PREFIX = "HasPermission";
    public AuthorizeWithPermissionAttribute(string permission) { // logic excluded for brevity }

    public string Permission 
    { 
        get { // code }
        set { // code }
    }
}
 

Затем я украшаю свой контроллер этим атрибутом следующим образом

 [AuthorizeWithPermission("MY_PERMISSION_NAME")]
public class MyController: ControllerBase
{
  // Controller logic.
}
 

До сих пор я пытался

  • Создание общедоступного конструктора без параметров для атрибута
  • Изменение типа (enum, int, string) параметра конструктора
  • Применяясь [OpenApiIgnore] к типу, а затем записывая пользовательский фильтр, Startup.cs когда это не сработало
  • Изменение модификатора доступа на уровне класса и свойства
  • Широкое применение атрибута к контроллеру и методам напрямую.

Вот ошибка, которую я получаю:

 Executing file 'nswag.json' with variables 'Configuration=Debug'...
3>    Launcher directory: %UserDirectory%.nugetpackagesnswag.msbuild13.8.2toolsNetCore31
3>    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
3>     ---> System.NullReferenceException: Object reference not set to an instance of an object.
3>       at %SLNNAME%.Authorization.Attributes.AuthorizeWithPermissionAttribute..ctor(String permission) in %SLNDirectory%AuthorizationAttributesAuthorizeWithPermissionAttribute.cs:line 14
3>       at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
3>       at System.Reflection.CustomAttribute.CreateCaObject(RuntimeModule module, RuntimeType type, IRuntimeMethodInfo ctor, IntPtramp; blob, IntPtr blobEnd, Int32amp; namedArgs)
3>       at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1amp; attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
3>       at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
3>       at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
3>       at System.RuntimeType.GetCustomAttributes(Boolean inherit)
3>       at Microsoft.AspNetCore.Mvc.ApplicationModels.DefaultApplicationModelProvider.CreateControllerModel(TypeInfo typeInfo)
3>       at Microsoft.AspNetCore.Mvc.ApplicationModels.DefaultApplicationModelProvider.OnProvidersExecuting(ApplicationModelProviderContext context)
3>       at Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModelFactory.CreateApplicationModel(IEnumerable`1 controllerTypes)
3>       at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetDescriptors()
3>       at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context)
3>       at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection()
3>       at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.Initialize()
3>       at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.get_ActionDescriptors()
3>       at Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider.get_ApiDescriptionGroups()
3>       at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.GenerateAsync(Object serviceProvider)
3>       at NSwag.AspNetCore.OpenApiDocumentProvider.GenerateAsync(String documentName)
3>       at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.GenerateDocumentWithDocumentProviderAsync(IServiceProvider serviceProvider) in C:projectsnswagsrcNSwag.CommandsCommandsGenerationAspNetCoreAspNetCoreToOpenApiCommand.cs:line 287
3>       at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.GenerateDocumentAsync(AssemblyLoader assemblyLoader, IServiceProvider serviceProvider, String currentWorkingDirectory) in C:projectsnswagsrcNSwag.CommandsCommandsGenerationAspNetCoreAspNetCoreToOpenApiCommand.cs:line 276
3>       at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.<>c__DisplayClass0_0.<<Process>b__0>d.MoveNext() in C:projectsnswagsrcNSwag.CommandsCommandsGenerationAspNetCoreAspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 30
3>    --- End of stack trace from previous location where exception was thrown ---
3>       at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.Process(String commandContent, String outputFile, String applicationName) in C:projectsnswagsrcNSwag.CommandsCommandsGenerationAspNetCoreAspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 29
3>       --- End of inner exception stack trace ---
3>       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
3>       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
3>       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
3>       at NSwag.AspNetCore.Launcher.Program.Main(String[] args) in C:projectsnswagsrcNSwag.AspNetCore.LauncherProgram.cs:line 170
3>    System.InvalidOperationException: Swagger generation failed with non-zero exit code '1'.
3>       at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:projectsnswagsrcNSwag.CommandsCommandsGenerationAspNetCoreAspNetCoreToOpenApiCommand.cs:line 221
3>       at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in C:projectsnswagsrcNSwag.CommandsNSwagDocumentBase.cs:line 280
3>       at NSwag.Commands.NSwagDocument.ExecuteAsync() in C:projectsnswagsrcNSwag.CommandsNSwagDocument.cs:line 81
3>       at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in C:projectsnswagsrcNSwag.CommandsCommandsDocumentExecuteDocumentCommand.cs:line 86
3>       at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:projectsnswagsrcNSwag.CommandsCommandsDocumentExecuteDocumentCommand.cs:line 32
3>       at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
3>       at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
3>       at NConsole.CommandLineProcessor.Process(String[] args, Object input)
3>       at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:projectsnswagsrcNSwag.CommandsNSwagCommandProcessor.cs:line 56
3>    %SLNDirectory%.csproj(59,5): error MSB3073: The command "dotnet "%UserDirectory%.nugetpackagesnswag.msbuild13.8.2build../tools/NetCore31/dotnet-nswag.dll" run nswag.json /variables:Configuration=Debug" exited with code -1.
3>  Done executing task "Exec" -- FAILED.
 

Ответ №1:

ЛОГИКА! ПРОБЛЕМА заключалась В логике в конструкторе. Здесь это работает. Надеюсь, кто-то не потратит на это два часа своей жизни, как я

 public class AuthorizeWithPermissionAttribute : AuthorizeAttribute
{
    const string POLICY_PREFIX = "HasPermission";
    public AuthorizeWithPermissionAttribute(string permission)
    {
       this.Permission = permission;
    }

    public string Permission { get => Policy; set => Policy = $"{POLICY_PREFIX}{value}"; }
}