1

Maybe there are some sort of permissions I need to set up in the test webhost ? The Get and Post for the tests work fine. But get a HTTP 405 error when it tries to call the DELETE method on the controller.

    [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 : Here is the method in the test project that makes the call

 [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);
    }
punkouter
  • 5,170
  • 15
  • 71
  • 116
  • Have you tried to remove the parameter in the httpdelete? maybe you are calling it in a badly way. Just [HttpDelete] and check what happens – aepelman Mar 11 '20 at 20:23
  • 1
    then the error is NOT FOUND since it is looking for a parameter.. I noticed UPDATE commands are giving the 405 too.. yet the GET and the POST are working fine :\ – punkouter Mar 11 '20 at 20:37
  • 1
    How is the url path you are calling? find the api endpoints in swagger and check how they should be called. please check if you are calling it exactly the same way as you have it in swagger – aepelman Mar 11 '20 at 20:55
  • How do you host your app against which you run your tests? There're some hints: you might run against old version of the app in which httDelete had not been implemented. If you host in IIS or IISExpress, check web config it defines which methods are allowed. – Sergey L Mar 11 '20 at 21:47
  • 405 is Method Not Allowed.... We need to see the code you are using to call the api and the api controllers' declaration – Jonathan Alfaro Mar 11 '20 at 21:53
  • I am using the IWebHostBuilder so my best guess is maybe there is some security issue not present in IIS Express – punkouter Mar 12 '20 at 15:54
  • Show us the route attribute on controller. Also, did you check the network tab of your browser to see what is the url swagger constructs and calls? – Mat J Mar 12 '20 at 16:29
  • [HttpDelete("{id:int}")]….. I changed it to [HttpGet("{id:int}")] and it works fine... Something about how it creates the web host in test it doesn't like.. I added the client to the CORS statement which is http://localhost but still doesn't like DELETE or PUT verbs – punkouter Mar 12 '20 at 16:51

3 Answers3

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

This is wrong, you are calling GetAsync, you are supposed to call DeleteAsync as you have marked your method with [HttpDelete] verb.

    HttpResponseMessage responseDelete = await Client.DeleteAsync("/api/RfAttachment/DeleteById/1");
    responseDelete.EnsureSuccessStatusCode();
Akash Kava
  • 39,066
  • 20
  • 121
  • 167
1

If your IWebHost is running under IIS / IISExpress, you may need to enable PUT and DELETE on IIS.

The following items must be set to enable:

  • Website Application Pool Managed Pipeline Mode must be set to Integrated
  • HTTP Verbs must be supported in IIS

Set Application Pool Pipeline Mode

  • Go to IIS Manager > Application Pools
  • Locate Application Pool for target:
    • (website) > Edit (double-click) > Managed pipeline mode: Integrated

HTTP Verb Update

The following snippet should be added to web.config to enable all verbs, and to ensure that WebDAV does not intercept and reject PUT and DELETE. If the default WebDAV is configured, WebDAV will intercept PUT and DELETE verbs, returning 405 errors (method not allowed).

<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>

If you prefer a GUI to add verbs, go to IIS Manager > Handler Mappings. Find ExtensionlessUrlHandler-Integrated-4.0, double click it. Click Request Restrictions... button and on Verbs tab, add both DELETE and PUT.

IIS Verbs

Eric Patrick
  • 2,097
  • 2
  • 20
  • 31
0

See more details in this post .netcore PUT method 405 Method Not Allowed

Include this line in the Web.Config file

<configuration> 
    <system.webServer>
        <modules>
             <remove name="WebDAVModule" />
        </modules>
    </system.webServer>
</configuration>
César Augusto
  • 593
  • 1
  • 7
  • 7