0

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.

Tony
  • 438
  • 1
  • 4
  • 10
  • After IIS receives your HTTP request and before ASP.NET Core handles that request, there are tons of things in between can alter the request due to IIS extensibility. Thus, enable FRT and see what exactly happens behind the scene, https://learn.microsoft.com/en-us/iis/troubleshoot/using-failed-request-tracing/troubleshoot-with-failed-request-tracing – Lex Li Jan 09 '23 at 07:36

1 Answers1

0

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.

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43