asp.net-coreiisjson-patch

PATCH request losing body on IIS but not on localhost


I have a web API, where I'm trying to support a PATCH request with a JSON Patch body to make changes to an object on the server.

I am using ASP Core with .Net 6, hosting using IIS on my web host.

This is the controller method:

public class BaseDataController<TEntity, TDetail, TNew> : ControllerBase
            where TEntity : class, IIdentifiable
{
        [HttpPatch("{id}")]
        public virtual async Task<ActionResult<TDetail>> Patch(Guid id, [FromBody] JsonPatchDocument<TEntity> patch)
        {
            var item = await MainService.GetAsync(id);

            if (item == null)
            {
                ControllerLogger.ItemNotFound();
                return NotFound();
            }

            patch.ApplyTo(item, ModelState);

            ValidationHelper.ValidatePatch(item, ModelState);

            if (!ModelState.IsValid)
                return BadRequest(ModelState);

            await MainService.UpdateAsync(item);
            return this.GuardResult(Mapper, item);
        }
}

When I try to use this on my local machine, it works just fine. When I deploy to my web server, and make an identical request, I get a validation error and a 400 status code:

{"errors":{"":["A non-empty request body is required."],"patch":["The patch field is required."]}}

If I change HttpPatch to HttpPost and update the web request accordingly, it works fine.

Can anyone suggest what might be going wrong here? I'm assuming the server is baulking at the PATCH verb, but I can't work out how to make it happy. Googling is coming up with a load of WebDAV things, but the error codes don't match and ASP is clearly receiving the request (proven from the logs) when the description of the WebDAV issues suggests it wouldn't.

My working theory is that IIS is seeing the PATCH verb and doing something to the request body that ASP Core doesn't like, but I can't work out why or where to look to turn that sort of thing off.


Solution

  • When I try to use this on my local machine, it works just fine. When I deploy to my web server, and make an identical request, I get a validation error and a 400 status code: If I change HttpPatch to HttpPost and update the web request accordingly, it works fine

    Well, your scenario is pretty obvious in context of IIS as you may know Http verb PATCH is not enabled as default accepted http verb on IIS Request Restrictions As you can see below:

    enter image description here

    Solution:

    To resolve above incident, you outght to configure Request Restrictions on IIS and need to include ,PATCH so that it will allow http PATCH verb. On top of that, after that, please restart your application pool. You can follow below steps to implement that:

    Step: 1

    Select your app on IIS and then click on Handler Mappings Just as following

    enter image description here

    Step: 2

    Select (Double click) ExtensionlessUrlHandler-Integrated-4.0

    enter image description here

    Step: 3

    Click on Request Restrictions

    enter image description here

    Step: 4

    Select VERB then include PATCH by comma seperated value as ,PATCH and click OK finally restart your application pool.

    enter image description here

    Note: For more details you can have a look on our official document here.