简体   繁体   English

可选参数在Swashbuckle.AspNetCore中导致空异常

[英]Optional parameter causes null exception in Swashbuckle.AspNetCore

I have an asp.net core 2.0 api controller action with an optional (and nullable) parameter. 我有一个带有可选(和可为空)参数的asp.net core 2.0 api控制器动作。 Swashbuckle.AspNetCore 1.0.0 generation of Swagger documentation fails when this parameter is present in the method signature, but succeeds if I remove it from the signature. 当方法签名中存在此参数时,Swagger文档的Swashbuckle.AspNetCore 1.0.0生成会失败,但是如果我从签名中删除它,则会成功。 It appears the optional parameter is the cause of the error but I can't tell why... 看来可选参数是导致错误的原因,但我不知道为什么...

I am using Swashbuckle integration with aspnet-api-versioning: https://github.com/Microsoft/aspnet-api-versioning/wiki/Swashbuckle-Integration 我正在将Swashbuckle集成与aspnet-api-versioning一起使用: https : //github.com/Microsoft/aspnet-api-versioning/wiki/Swashbuckle-Integration

Controller action : 控制器动作

[HttpGet("{id}")]
public IActionResult GetPerson(int id, [FromQuery] bool? includeContactInfo = null)
{
    var includeInfo = (includeContactInfo.HasValue && includeContactInfo.Value == true);
    var person = _repo.GetPerson(id, includeInfo);
    if (person == null)
    {
        return NotFound();
    }

    if (includeInfo)
    {
        // using AutoMapper to map between entity and dto
        var personFullDto = Mapper.Map<PersonFullDto>(person);
        return Ok(personFullDto);
    }

    var personBasicDto = Mapper.Map<PersonBasicDto>(person);
    return Ok(personBasicDto);
}

Here are the ConfigureServices and Configure methods from my startup.cs : 这是我的startup.cs中的ConfigureServicesConfigure方法:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore().AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
    services.AddMvc();

    services.AddApiVersioning(o =>
    {
        o.ReportApiVersions = true;
        o.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
    });

    services.AddSwaggerGen(options =>
    {
        var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
        foreach (var description in provider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
        }
        options.OperationFilter<SwaggerDefaultValues>();
        options.IncludeXmlComments(XmlCommentsFilePath);
    });

    var connectString = Startup.Configuration["connectionStrings:ContactsAppDb"];
    services.AddDbContext<ContactsDbContext>(o => o.UseSqlServer(connectString));
    services.AddScoped<IContactsRepository, ContactsRepository>();
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
{
    if (env.IsEnvironment("PROD"))
    {
        app.UseExceptionHandler();
    }
    else
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStatusCodePages();

    AutoMapper.Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<Entities.Person, Models.PersonBasicDto>();
        cfg.CreateMap<Entities.Person, Models.PersonFullDto>();
        cfg.CreateMap<Entities.ContactInfo, Models.ContactInfoDto>();
    });

    app.UseMvc();

    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        // build a swagger endpoint for each discovered API version
        foreach (var description in provider.ApiVersionDescriptions)
        {
            options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
        }
    });
}

I am also using the SwaggerDefaultValues.cs class, from https://github.com/Microsoft/aspnet-api-versioning/wiki/Swashbuckle-Integration#aspnet-core 我也在使用SwaggerDefaultValues.cs类,来自https://github.com/Microsoft/aspnet-api-versioning/wiki/Swashbuckle-Integration#aspnet-core

public class SwaggerDefaultValues : IOperationFilter
{
    public void Apply( Operation operation, OperationFilterContext context )
    {
        foreach ( var parameter in operation.Parameters.OfType<NonBodyParameter>() )
        {
            var description = context.ApiDescription
                                     .ParameterDescriptions
                                     .First( p => p.Name == parameter.Name );

            if ( parameter.Description == null )
            {
                parameter.Description = description.ModelMetadata.Description;
            }

            if ( parameter.Default == null )
            {
                parameter.Default = description.RouteInfo.DefaultValue;
            }

            parameter.Required |= !description.RouteInfo.IsOptional;
        }
    }
}

When I navigate to the Swagger URL, the following line of code fails (in the SwaggerDefaultValues.cs class): 当我导航到Swagger URL时,以下代码行失败(在SwaggerDefaultValues.cs类中):

parameter.Default = description.RouteInfo.DefaultValue;

When I inspect the description object for the includeContactInfo optional/query parameter, the description.RouteInfo is null. 当我检查description对象的includeContactInfo可选/查询参数时, description.RouteInfo为null。

Error message: 错误信息:

Object reference not set to an instance of an object.

Stack trace: 堆栈跟踪:

at ContactsApp.Services.SwaggerDefaultValues.Apply(Operation operation, OperationFilterContext context) in C:\Users\me\Documents\Visual Studio 2017\Projects\ContactsApp\ContactsApp\Services\SwaggerDefaultValues.cs:line 37
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreateOperation(ApiDescription apiDescription, ISchemaRegistry schemaRegistry)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItem(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.<Invoke>d__6.MoveNext()

使用空条件运算符:

parameter.Default = description.RouteInfo?.DefaultValue;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swashbuckle.AspNetCore-无法为继承基本控制器的控制器生成json - Swashbuckle.AspNetCore - Unable to generate json for controllers that inherit base controllers 迁移到 Swashbuckle.AspNetCore 版本 5 时,Swagger UI 中的不记名身份验证 - Bearer authentication in Swagger UI, when migrating to Swashbuckle.AspNetCore version 5 Swashbuckle.AspNetCore openapi 架构中未正确显示可空属性 - Nullable property is not presented in the Swashbuckle.AspNetCore openapi schema properly 无法解析 .net5.0 的“Swashbuckle.AspNetCore (>= 5.6.3)” - Unable to resolve 'Swashbuckle.AspNetCore (>= 5.6.3)' for 'net5.0' 多版本控制 URL 在 Swashbuckle.AspNetCore 5.0.0rc 中不起作用 - Multiple versioning URL not working in Swashbuckle.AspNetCore 5.0.0rc Swashbuckle.AspNetCore (5.0.0-rc5) 忽略公共字段 - Swashbuckle.AspNetCore (5.0.0-rc5) ignoring public fields 如何使用Swashbuckle.AspNetCore隐藏响应代码200? - How can I hide response code 200 with Swashbuckle.AspNetCore? swashbuckle.aspnetcore 是否支持 asp.net core 3.0? - Is swashbuckle.aspnetcore supporting asp.net core 3.0? Swashbuckle.AspNetCore是否支持FluentValidation而不是DataAnnotations? - Does Swashbuckle.AspNetCore support FluentValidation instead of DataAnnotations? Swashbuckle.AspNetCore仅生成带有字符串类型字段的模型 - Swashbuckle.AspNetCore only generating models with fields of type string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM