1. ホーム
  2. c#

[解決済み] ASP.Net Core + Swagger - Swagger 2.0では、アクションに明示的なHttpMethodバインディングが必要です。

2022-02-09 15:36:20

質問

あるプロジェクトがあります。 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() {...}
    }
}

そして スタートアップ.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 が、これもうまくいきませんでした。

私は何を間違えているのでしょうか?

どうすればいいですか?

として devNull が言ったように、間違いは私のコードではなく WebEssentials.AspNetCore.Pwa.PwaController.ServiceWorkerAsync .

UPDATE

プル リクエスト を修正したもの(明示的な HttpMethod バインディングを追加)は、現在 WebEssentials.AspNetCore.ServiceWorker のリポジトリで公開され、次のリリースで利用できるようになる予定です。 ニューゲット バージョン 新しい よりも 1.0.59

OLD SOLUTIONです。

次のような解決策が掲載されているのを見つけました。 ここで によって ガンディー .

  1. どこかにクラスを作成する ApiExplorerIgnores を以下の内容で作成します。
public class ApiExplorerIgnores : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        if (action.Controller.ControllerName.Equals("Pwa"))
            action.ApiExplorer.IsVisible = false;
    }
}

  1. メソッドに以下のコードを追加します。 サービス構成 スタートアップ.cs
services.AddMvc(c => c.Conventions.Add(new ApiExplorerIgnores()))

これは PwaController から ApiExplorer で使用されている スワッシュバックル .