Swashbuckle.AspNetCore - 无法为继承基本控制器的控制器生成 json
Swashbuckle.AspNetCore - Unable to generate json for controllers that inherit base controllers
我有两个继承其他控制器的控制器 - 对于其中一个,会生成 swagger 文档,而对于另一个则不会。
我的控制器是:
[Route("Actor")]
public class ActorController : BaseDefControllerLog<Actor>
{
public ActorController(BaseDefController<Actor> baseController, ILogger<ActorController> logger, IAppConfig appSettings) : base(baseController, logger, appSettings)
{ }
}
[Route("ActorCatalog")]
public class ActorCatalogController: LoggerController, ICatalogController<Actor>
{
private readonly BaseDefControllerLog<Actor> _baseController;
public ActorCatalogController(BaseDefControllerLog<Actor> baseController, ILogger<ActorCatalogController> logger) : base(logger)
{
_baseController = baseController;
}
[Route("GetAll")]
[HttpGet]
public ICollection<Actor> GetAll(int? pageNumber = null, int? pageSize = null)
{
//GetAll logic
}
}
下面是 BaseDefController、BaseDefControllerLog 和 LoggerController:
public class BaseDefController<T> : Controller, ICatalogController<T> where T : class, IConfigDef
{
private readonly IReadManager<T> _manager;
public BaseDefController(IReadManager<T> manager)
{
_manager = manager;
}
[HttpGet]
public virtual ICollection<T> GetAll(int? pageNumber = null, int? pageSize = null)
{
return _manager.GetAll(pageNumber, pageSize);
}
}
public class BaseDefControllerLog<T>: LoggerController where T : class, IConfigDef
{
private readonly BaseDefController<T> _baseController;
private readonly ILogger<BaseDefControllerLog<T>> _logger;
public BaseDefControllerLog(BaseDefController<T> baseController, ILogger<BaseDefControllerLog<T>> logger, IAppConfig appSettings) : base(logger)
{
_baseController = baseController;
_logger = logger;
}
[HttpGet]
public virtual ICollection<T> GetAll(string remoteIpAddress = null, int? pageNumber = null, int? pageSize = null)
{
//GetAll logic
}
}
public class LoggerController : Controller
{
protected ILogger Logger;
public LoggerController(ILogger logger)
{
Logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{ //... }
public override void OnActionExecuted(ActionExecutedContext context)
{ //... }
}
"Actor" 模型很简单 class:
public class Actor : IConfigDef
{
public int Id { get; set; }
public Guid Tag { get; set; }
public string Name { get; set; }
public DateTime LastUpdated { get; set; }
public bool Deleted { get; set; }
}
版本:
Swashbuckle.AspNetCore 1.0.0
重现步骤:
我已经用 Route 属性装饰了 ActorController 和 ActorCatalogController。此时swagger在生成json时抛出异常。如果我删除 ActorController 上的路由并因此仅为 ActorCatalogController 生成文档,则一切正常。如果我用路由属性装饰继承控制器的操作,我也会在 json 上得到 500 响应。我也尝试删除 virtual 关键字,但没有成功。
预期结果:
两个控制器(ActorCatalogController 和 ActorController)的文档。
实际结果:
500 人:http://localhost:4100/swagger/v1/swagger.json
无法生成 JSON。我发现了这个异常:"Exception thrown: 'System.NotSupportedException' in Swashbuckle.AspNetCore.SwaggerGen.dll".
其他详细信息
我项目的目标框架是.NET Framework 4.6.2。我使用 Microsoft.AspNetCore 1.1.2 和 Microsoft.AspNetCore.Hosting.WindowsServices 1.1.2。
我在 Startup.cs 中的 swagger 配置如下:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc(config =>
{
config.RespectBrowserAcceptHeader = true;
})
.AddJsonOptions(options =>
{
options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
})
.AddXmlSerializerFormatters();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "InternalServer", Version = "v1" });
});
InitializeContainer(services);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "SwaggerDemo V1");
});
LogRegistration(loggerFactory);
}
我解决了这个问题,有关解决方法的更多详细信息,请参见此处:https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/511
我有两个继承其他控制器的控制器 - 对于其中一个,会生成 swagger 文档,而对于另一个则不会。 我的控制器是:
[Route("Actor")]
public class ActorController : BaseDefControllerLog<Actor>
{
public ActorController(BaseDefController<Actor> baseController, ILogger<ActorController> logger, IAppConfig appSettings) : base(baseController, logger, appSettings)
{ }
}
[Route("ActorCatalog")]
public class ActorCatalogController: LoggerController, ICatalogController<Actor>
{
private readonly BaseDefControllerLog<Actor> _baseController;
public ActorCatalogController(BaseDefControllerLog<Actor> baseController, ILogger<ActorCatalogController> logger) : base(logger)
{
_baseController = baseController;
}
[Route("GetAll")]
[HttpGet]
public ICollection<Actor> GetAll(int? pageNumber = null, int? pageSize = null)
{
//GetAll logic
}
}
下面是 BaseDefController、BaseDefControllerLog 和 LoggerController:
public class BaseDefController<T> : Controller, ICatalogController<T> where T : class, IConfigDef
{
private readonly IReadManager<T> _manager;
public BaseDefController(IReadManager<T> manager)
{
_manager = manager;
}
[HttpGet]
public virtual ICollection<T> GetAll(int? pageNumber = null, int? pageSize = null)
{
return _manager.GetAll(pageNumber, pageSize);
}
}
public class BaseDefControllerLog<T>: LoggerController where T : class, IConfigDef
{
private readonly BaseDefController<T> _baseController;
private readonly ILogger<BaseDefControllerLog<T>> _logger;
public BaseDefControllerLog(BaseDefController<T> baseController, ILogger<BaseDefControllerLog<T>> logger, IAppConfig appSettings) : base(logger)
{
_baseController = baseController;
_logger = logger;
}
[HttpGet]
public virtual ICollection<T> GetAll(string remoteIpAddress = null, int? pageNumber = null, int? pageSize = null)
{
//GetAll logic
}
}
public class LoggerController : Controller
{
protected ILogger Logger;
public LoggerController(ILogger logger)
{
Logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{ //... }
public override void OnActionExecuted(ActionExecutedContext context)
{ //... }
}
"Actor" 模型很简单 class:
public class Actor : IConfigDef
{
public int Id { get; set; }
public Guid Tag { get; set; }
public string Name { get; set; }
public DateTime LastUpdated { get; set; }
public bool Deleted { get; set; }
}
版本:
Swashbuckle.AspNetCore 1.0.0
重现步骤:
我已经用 Route 属性装饰了 ActorController 和 ActorCatalogController。此时swagger在生成json时抛出异常。如果我删除 ActorController 上的路由并因此仅为 ActorCatalogController 生成文档,则一切正常。如果我用路由属性装饰继承控制器的操作,我也会在 json 上得到 500 响应。我也尝试删除 virtual 关键字,但没有成功。
预期结果:
两个控制器(ActorCatalogController 和 ActorController)的文档。
实际结果:
500 人:http://localhost:4100/swagger/v1/swagger.json 无法生成 JSON。我发现了这个异常:"Exception thrown: 'System.NotSupportedException' in Swashbuckle.AspNetCore.SwaggerGen.dll".
其他详细信息
我项目的目标框架是.NET Framework 4.6.2。我使用 Microsoft.AspNetCore 1.1.2 和 Microsoft.AspNetCore.Hosting.WindowsServices 1.1.2。 我在 Startup.cs 中的 swagger 配置如下:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc(config =>
{
config.RespectBrowserAcceptHeader = true;
})
.AddJsonOptions(options =>
{
options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
})
.AddXmlSerializerFormatters();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "InternalServer", Version = "v1" });
});
InitializeContainer(services);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "SwaggerDemo V1");
});
LogRegistration(loggerFactory);
}
我解决了这个问题,有关解决方法的更多详细信息,请参见此处:https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/511