当 运行 我的测试(405 方法不允许)时,无法在 ASP.NET 核心中调用 API DELETE。但它大摇大摆地工作

Cannot call API DELETE in ASP.NET core when running my tests (405 Method Not Allowed) . BUT it works in swagger

也许我需要在测试虚拟主机中设置某种权限?测试的 Get 和 Post 工作正常。但是当它尝试调用控制器上的 DELETE 方法时出现 HTTP 405 错误。

    [HttpDelete("{id:int}")]
    public async Task<ActionResult<RfAttachmentModel>> DeleteByIdAsync(int id)
    {
        await _rfAttachmentService.DeleteByIdAsync(id);
        return NoContent();
    }


  public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseEnvironment("LocalTesting");

        builder.ConfigureServices(services =>
        {
            services.AddEntityFrameworkInMemoryDatabase();

            ServiceProvider provider = services
                .AddEntityFrameworkInMemoryDatabase()
                .BuildServiceProvider();

            services.AddDbContext<PwdrsContext>(options =>
            {
                options.UseInMemoryDatabase("Pwdrs");
                options.UseInternalServiceProvider(provider);
            });

            ServiceProvider sp = services.BuildServiceProvider();

            using (IServiceScope scope = sp.CreateScope())
            {
                IServiceProvider scopedServices = scope.ServiceProvider;
                PwdrsContext db = scopedServices.GetRequiredService<PwdrsContext>();
                ILoggerFactory loggerFactory = scopedServices.GetRequiredService<ILoggerFactory>();

                ILogger<CustomWebApplicationFactory<TStartup>> logger = scopedServices
                    .GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();

                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                try
                {
                    PwdrsContextSeed.SeedAsync(db, loggerFactory).Wait();
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, $"An error occurred seeding the " +
                        "database with test messages. Error: {ex.Message}");
                }
            }
        });
    }
}

EDIT1:这是测试项目中进行调用的方法

 [Fact]
    public async Task Delete_Item_By_Id()
    {
        HttpResponseMessage responseDelete = await Client.GetAsync("/api/RfAttachment/DeleteById/1");
        responseDelete.EnsureSuccessStatusCode();

        HttpResponseMessage responseGetAll = await Client.GetAsync("/api/RfAttachment/GetAll");
        responseGetAll.EnsureSuccessStatusCode();
        string stringResponse = await responseGetAll.Content.ReadAsStringAsync();
        List<RfAttachment> result = JsonConvert
            .DeserializeObject<IEnumerable<RfAttachment>>(stringResponse)
            .ToList();

        Assert.Single(result);
    }

如果您的 IWebHost 在 IIS / IISExpress 下 运行,您可能需要在 IIS 上启用 PUT 和 DELETE。

必须设置以下项目才能启用:

  • 网站应用程序池托管管道模式必须设置为集成
  • IIS 必须支持 HTTP 动词

设置应用程序池管道模式

  • 转到 IIS 管理器 > 应用程序池
  • 找到目标的应用程序池:
    • (网站)> 编辑(双击)> 托管管道模式:集成

HTTP 动词更新

应将以下代码片段添加到 web.config 以启用所有动词,并确保 WebDAV 不会拦截和拒绝 PUTDELETE。如果配置了默认的WebDAVWebDAV会拦截PUTDELETE动词,返回405错误(方法不允许)。

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="WebDAV" />
      <add name="dotless" path="*.less" verb="GET" type="dotless.Core.LessCssHttpHandler,dotless.AspNet" resourceType="File" preCondition="" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
    </handlers>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
</system.webServer>

如果您更喜欢 GUI to add verbs,请转至 IIS 管理器 > 处理程序映射。找到 ExtensionlessUrlHandler-Integrated-4.0,双击它。单击 Request Restrictions... 按钮并在 Verbs 选项卡上,添加 DELETEPUT

    HttpResponseMessage responseDelete = await Client.GetAsync("/api/RfAttachment/DeleteById/1");
    responseDelete.EnsureSuccessStatusCode();

这是错误的,您正在调用 GetAsync,您应该调用 DeleteAsync,因为您用 [HttpDelete] 动词标记了您的方法。

    HttpResponseMessage responseDelete = await Client.DeleteAsync("/api/RfAttachment/DeleteById/1");
    responseDelete.EnsureSuccessStatusCode();

在此查看更多详细信息 post

在 Web.Config 文件中包含这一行

<configuration> 
    <system.webServer>
        <modules>
             <remove name="WebDAVModule" />
        </modules>
    </system.webServer>
</configuration>