【问题标题】:ASP.Net Core + Swagger - Actions require an explicit HttpMethod binding for Swagger 2.0ASP.Net Core + Swagger - 操作需要 Swagger 2.0 的显式 HttpMethod 绑定
【发布时间】:2019-08-11 23:02:35
【问题描述】:

我有一个项目MyProject.Api,其结构如下:

Controllers/
- Api/
  - UsersController.cs
- HomeController.cs
Startup.cs

HomeController.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() {...}
    }
}

UsersController.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() {...}
    }
}

Startup.cs


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"});
                });
            });
        }
    }
}

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

Fetch error
Internal Server Error /swagger/v1/swagger.json

并且在服务器端出现此错误

System.NotSupportedException: Ambiguous HTTP method for action - WebEssentials.AspNetCore.Pwa.PwaController.ServiceWorkerAsync (WebEssentials.AspNetCore.Pwa). Actions require an explicit HttpMethod binding for Swagger 2.0
   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(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

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

我做错了什么?

【问题讨论】:

  • 堆栈跟踪表明WebEssentials.AspNetCore.Pwa.PwaController.ServiceWorkerAsync 处的方法需要显式的 HttpMethod 绑定。不幸的是,控制器在第三方库中。所以你最好的选择是不使用那个库
  • @devNull 我一定是瞎子!谢谢!
  • 我通过将 [HttpGet] 添加到相关的 Action 解决了同样的问题。

标签: c# asp.net asp.net-core asp.net-web-api swagger


【解决方案1】:

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

更新:

我的 pull request 带有修复(添加显式 HttpMethod 绑定)现在已合并到 WebEssentials.AspNetCore.ServiceWorker 存储库,并有望在 NuGet 的下一个版本中提供,版本 更新 1.0.59

旧解决方案:

我找到了Gandiihere 发布的以下解决方案。

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

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

【讨论】:

  • 不包含在 1.0.59 中,我只是遇到了这个问题。不过,“旧”解决方案对我有用。
  • 太棒了。我喜欢 Mads,但现在这似乎是他需要做的第二个项目,并且似乎永远不会回到它。我想在我打了他一次之后就和他一起喝啤酒。
  • 我刚刚在方法上添加了 [HttpGet],它工作正常。环境 .Net Core 3.1 和 SwashBuckle 5.1
  • 现在您可以添加 [ApiExplorerSettings(IgnoreApi = true)] 以忽略 Swagger 从文档中包含控制器。这也有助于防止出现此问题。
【解决方案2】:

有同样的错误,但它是不同的解决方案。将 master 合并到我的分支时,我删除了控制器中在调试控制台中编写的函数上方的 [HttpGet]。希望我的经验对某人有所帮助

【讨论】:

    【解决方案3】:

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

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

    例子:

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

    DoStuff的访问修饰符更改为internal解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 2021-05-15
      相关资源
      最近更新 更多