Skip to content

HttpPatch with body returns 415 #1

@Tomas-Niemczyk

Description

@Tomas-Niemczyk

A controller created by ControllerFactory returns httpcode 415 when calling a http patch method with a body.

Replicable example:

Out of the box WebAPI project with a patch endpoint:

[Route("patch")]
[HttpPatch]
public virtual ActionResult Patch([FromBody] object _)
{
    return Ok();
}

Test calling this endpoint through a controller created by ControllerFactory:

[Test]
public async Task Patch()
{
    await using var webAppFactory = new WebApplicationFactory<Startup>();
    var client = webAppFactory.CreateClient();
    var controllerFactory = new ControllerFactory(
        client,
        webAppFactory.Services,
        new NunitLogWriter());
    var testController = controllerFactory.CreateController<TestController>();

    var response = testController.Patch(new object());

    Assert.That(response.IsSuccessStatusCode());
}

Expected:

Status code 200 returned.

Actual:

Status code 415 returned.

Remarks:

The exact same code works when the endpoint is changed to [HttpPost]
Adding an IHttpRequestPipelinePart to the request chain reveals that the content is for some reason null which clarifies the 415 unsupported media type response (request is being sent without a body and a Content-Type header when one is expected)

public class ContentLoggingPipelinePart : IHttpRequestPipelinePart
{
    public async Task<HttpResponseMessage> InvokeAsync(Func<Task<HttpResponseMessage>> next, HttpRequestMessage httpRequestMessage, IReadOnlyActionInfo actionInfo, InvocationInfo invocationInfo)
    {
        Console.WriteLine(httpRequestMessage.Content is null
            ? "Content is null"
            : await httpRequestMessage.Content.ReadAsStringAsync());
        return await next();
    }
}

controllerFactory.AddHttpRequestPipelinePart(new ContentLoggingPipelinePart());

Workaround:

Calling the patch endpoint manually

[Test]
public async Task Patch()
{
    await using var webAppFactory = new WebApplicationFactory<Startup>();
    var client = webAppFactory.CreateClient();

    var request = new HttpRequestMessage(HttpMethod.Patch, "/patch")
    {
        Content = new StringContent(JsonConvert.SerializeObject(new object()), Encoding.UTF8, MediaTypeNames.Application.Json)
    };

    var response = await client.SendAsync(request);

    Assert.That(response.IsSuccessStatusCode);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions