Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core 2.2 WebAPI 405 Method Not Allowed

Setup

  • Windows 10
  • Visual Studio 2017 Professional
  • ASP.Net Core 2.2

What I'm trying to do

Run an Integration Test against a controller method in my Web API that uses a PATCH verb

MyController.cs

namespace FluidIT.API.Controllers
{
    [Route("api/v1/[controller]")]
    [ApiController]
    public class MyController : ControllerBase
    {
        private readonly IMediator _mediator;
        private readonly IMyQueries _myQueries;

        public JobsController(IMediator mediator, IMyQueries myQueries)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _myQueries = myQueries ?? throw new ArgumentNullException(nameof(myQueries));
        }

        // PATCH: api/v1/my/{id}
        [Route("id:int")]
        [HttpPatch]
        public async Task<IActionResult> RemoveMeAsync(int id)
        {
            bool commandResult = false;

            try
            {
                commandResult = await _mediator.Send(new RemoveMeCommand(id));
                return NoContent();
            }
            catch (NotFoundException)
            {
                return NotFound(id);
            }
        }
    }
}

MyIntegrationTest.cs

[Fact]
async Task Patch_MyAsync_WhenIdNotFound_ReturnsNotFoundStatusCode()
{
    // Arrange
    var request = new HttpRequestMessage()
    {
        RequestUri = new Uri($"{_fixture.Client.BaseAddress}{_baseRoute}/1"),
        Method = HttpMethod.Patch,
        Headers =
        {
            { HttpRequestHeader.ContentEncoding.ToString(), Encoding.UTF8.ToString() },
            { HttpRequestHeader.ContentType.ToString(), "application/json" }
        }
    };

    // Act
    var response = await _fixture.Client.SendAsync(request);

    // Assert
    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

What I've done so far

I've seen that this is a fairly common occurrence when trying to use the PUT, PATCH or DELETE http verbs. I've also seen that adding the following to a web.config file to remove the webDAV module from IIS is the suggested solution

Stackoverflow answer
A blog post

web.config

<?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
          <modules runAllManagedModulesForAllRequests="false">
            <remove name="WebDAVModule" />
          </modules>
    </system.webServer>
</configuration>

However, as you've probably guessed, this solution isn't working for me. My test returns a 405 MethodNotAllowed response.

Most of the info on this topic seem to be from a while ago, so I thought I'd ask the question here specifically for an ASP.NET Core API.

like image 492
GreenyMcDuff Avatar asked May 04 '19 14:05

GreenyMcDuff


People also ask

How do I fix 405 Method not allowed in iis?

If you don't need to use WebDAV, then the easiest and the best way to fix "405 method not allowed" issue is to remove WebDAV from your system. You can easily get this done in "Turn Windows Features On or Off" simply un-ticking the checkbox.

How do I open Webapi?

You can use any HTTP client to invoke your web API. In fact, you can invoke it directly from a web browser. In Visual Studio, start your application in debugging mode. Visual Studio will automatically open a web browser window with URL that points to http://localhost<portnumber>.

What is Webapi in C#?

Web API is a programming interface/application type that provides communication or interaction between software applications. Web API is often used to provide an interface for websites and client applications to have data access. Web APIs can be used to access data from a database and save data back to the database.


1 Answers

To fix the issue, correct the route constraint syntax enclose the parameter and datatype inside curly braces [Route("{id:int}")]

[Route("{id:int}")]
[HttpPatch]
public async Task<IActionResult> RemoveMeAsync(int id)
{
    bool commandResult = false;

    try
    {
        commandResult = await _mediator.Send(new RemoveMeCommand(id));
        return NoContent();
    }
    catch (NotFoundException)
    {
        return NotFound(id);
    }
}
like image 178
Mohsin Mehmood Avatar answered Oct 05 '22 09:10

Mohsin Mehmood