当前位置: 首页 > 知识库问答 >
问题:

可选参数导致swashbuckle.aspnetcore中的null异常

卫子平
2023-03-14

我有一个ASP.NET Core2.0api控制器操作,其中包含一个可选(且为空)参数。swashbuckle.aspnetcore1.0.0如果方法签名中存在此参数,则生成Swagger文档将失败,但如果将其从签名中删除,则生成成功。似乎可选参数是错误的原因,但我不知道为什么...

我正在使用Swashbuckle与ASPNET-API-Versioning的集成:https://github.com/microsoft/ASPNET-API-Versioning/wiki/SwashBuckle-Integration

[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);
}
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());
        }
    });
}

我还使用了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;
        }
    }
}

当我导航到Swagger URL时,以下代码行失败(在SwaggerDefaultValues.cs类中):

parameter.Default = description.RouteInfo.DefaultValue;

当我检查description对象的IncludeContactInfo可选/query参数时,description.routeInfo为空。

错误消息:

Object reference not set to an instance of an object.

堆栈跟踪:

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()

共有1个答案

酆恩
2023-03-14

使用空条件运算符

parameter.Default = description.RouteInfo?.DefaultValue;
 类似资料:
  • 问题内容: Go可以有可选参数吗?还是可以只定义两个具有相同名称和不同数量参数的函数? 问题答案: Go没有可选参数,也不支持方法重载: 如果方法调度也不需要进行类型匹配,则可以简化该方法。其他语言的经验告诉我们,使用具有相同名称但签名不同的多种方法有时会很有用,但在实践中也可能会造成混淆和脆弱。在Go的类型系统中,仅按名称进行匹配并要求类型一致是简化的主要决定。

  • 我在行得到异常。怎么会呢?这到底是怎么回事? 这是我的密码。 堆栈跟踪

  • 问题内容: 我有一个用户定义的函数,该函数已在许多存储过程中使用,这些函数将为我返回一些值。如果可以的话,可以在其中添加一个新的可选参数。 如果我不传递任何值,则应为null;如果传递一些值,则应采用它。我不想去改变所有的存储过程。 范例程式码 我可以用吗 问题答案: 如果您不想调整所有引用该函数的现有存储过程,那么我认为您需要使用现有代码中的代码创建一个新函数 然后只需将现有功能更改为以下内容

  • 问题内容: 有人可以解释一下如何编写网址格式和允许可选参数的视图吗?我已成功完成此操作,但我总是会破坏url模板标记。 这是我目前所拥有的: 图案 视图 如果在此示例中使用提供两个参数的url模板标记,则效果很好;但是,如果省略可选参数,则会出现反向错误。 我该怎么做? 问题答案: 我通常使用命名的url制作两种模式:

  • 用户在这个插件的很多方面都可以进行定制,用户通过插件选项来达到这个目的(这些选项会在插件初始化的时候起效)。这些选项包括: 选项 描述 aspectRatio 长宽比,以后在选择时候就会维持不变。例如:"4:3" autoHide 如果设为true,那么在选择完后区域会消失。Default:false classPrefix 预先给插件元素的前缀 Default:imgareaselect dis

  • 英文原文:http://www.phpconcept.net/pclzip/user-guide/5 可选参数(普通参数) PCLZIP_OPT_PATH PCLZIP_OPT_ADD_PATH PCLZIP_OPT_REMOVE_PATH PCLZIP_OPT_REMOVE_ALL_PATH PCLZIP_OPT_SET_CHMOD PCLZIP_OPT_BY_NAME PCLZIP_OPT_B