ASP.Net Core + Swagger - 操作需要 Swagger 2.0 的显式 HttpMethod 绑定

ant*_*riz 7 c# asp.net asp.net-web-api swagger asp.net-core

我有一个项目MyProject.Api具有以下结构:

Controllers/
- Api/
  - UsersController.cs
- HomeController.cs
Startup.cs
Run Code Online (Sandbox Code Playgroud)

其中HomeController.cs看起来像这样:

Controllers/
- Api/
  - UsersController.cs
- HomeController.cs
Startup.cs
Run Code Online (Sandbox Code Playgroud)

UsersController.cs看起来像这样:

namespace MyProject.Api.Controllers
{
    public class HomeController : Controller
    {
        private readonly IHostingEnvironment _hostingEnvironment;

        public HomeController(IHostingEnvironment hostingEnv) {...}

        [HttpGet]
        public async Task<IActionResult> Index() {...}

        [HttpGet("sitemap.xml")]
        public IActionResult SiteMap() {...}

        [HttpGet("error")]
        public IActionResult Error() {...}
    }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs

namespace MyProject.Api.Controllers.Api
{
    [Route("api/[controller]")]
    public class UsersController : Controller
    {
        private readonly ApiHelper<UsersController> _apiHelper;
        private readonly IUserService _userService;

        public UsersController(ILogger<UsersController> logger, IUserService userService) {...}

        [HttpPost("login")]
        public async Task<JsonResult> Login([FromBody] LoginRequest request) {...}

        [HttpPost("register")]
        public async Task<JsonResult> Register([FromBody] RegisterRequest request) {...}

        [HttpGet("renew")]
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        public async Task<JsonResult> Renew() {...}
    }
}
Run Code Online (Sandbox Code Playgroud)

当我加载/swaggerUI 加载成功时,但出现以下错误:

Fetch error
Internal Server Error /swagger/v1/swagger.json
Run Code Online (Sandbox Code Playgroud)

并在服务器端出现此错误


namespace MyProjet.Api
{
    public class Startup
    {
        private IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration) {...}

        public void ConfigureServices(IServiceCollection services)
        {
            ...

            services.AddSwaggerGen(c => c.SwaggerDoc("v1", new Info {Title = "Web Api Docs", Version = "v1"}));
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ...

            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); });
            app.MapWhen(x => !x.Request.Path.Value.StartsWith("/swagger", StringComparison.OrdinalIgnoreCase), builder =>
            {
                builder.UseMvc(routes =>
                {
                    routes.MapSpaFallbackRoute(
                       "spa-fallback",
                        new {controller = "Home", action = "Index"});
                });
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但所有方法都有唯一的路由、唯一的名称,并且它们的 HTTP 方法是明确绑定的。我试过添加[Route("")]HomeController.cs,但这也不起作用。

我究竟做错了什么?

sc9*_*911 18

有同样的错误,但没有涉及任何第三方库。

我的代码中的问题是,public控制器基类中的方法被控制器使用,但不被控制器公开。

例子:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class TestController : GenericController<TestClass>
{
    public TestController() : base()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class GenericController<T1>
{
    public GenericController()
    {
    // ...
    }
    
    [HttpGet]
    public async Task<ActionResult<IEnumerable<T1>>> Get()
    {
    // ...
    }
    
    public void DoStuff()
    {
    // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

更改访问修饰符DoStuffinternal解决问题。


ant*_*riz 10

正如@devNull所说,错误不在我的代码中,而是在WebEssentials.AspNetCore.Pwa.PwaController.ServiceWorkerAsync.

更新:

我拉请求与修复(由明确列举HTTPMethod绑定)现在被合并到WebEssentials.AspNetCore.ServiceWorker库,并希望在明年发行版上的NuGet与版本更新1.0.59

旧解决方案:

我发现下面的解决方案张贴在这里Gandii

  1. 使用以下内容在某处创建类ApiExplorerIgnores
public class ApiExplorerIgnores : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        if (action.Controller.ControllerName.Equals("Pwa"))
            action.ApiExplorer.IsVisible = false;
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 下面的代码添加到方法ConfigureServicesStartup.cs
services.AddMvc(c => c.Conventions.Add(new ApiExplorerIgnores()))
Run Code Online (Sandbox Code Playgroud)

这应该隐藏Swashbuckle使用的ApiExplorer 中PwaController

  • 不包含在 1.0.59 中,我刚刚遇到了这个问题。不过,“旧”解决方案对我有用。 (2认同)

小智 6

我的问题是我的方法上面没有 [HttpGet] 来实际获取我想要的 api


小智 6

如果 Http 操作方法有参数,Swagger(至少 v3.0 及以下版本)将失败。因此,使用 [HttpPost] 而不是 [HttpPost("somename")]。