[英]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
中的ConfigureServices和Configure方法:
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.