JavaEar 专注于收集分享传播有价值的技术资料

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.

1个回答

    最佳答案
  1. 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);
                    }
                }