Как сделать запрос PATCH для API с ASP.NET Core 2.2?

У меня есть приложение, которое написано с использованием C# на вершине ASP.NET Core 2.2. Я создал контроллер, который отвечает на PATCH запрос называется Update, Вот мой контроллер

[Route("api/[controller]"), ApiController, Produces("application/json")]
public class CategoriesController : ControllerBase
{
    [HttpPatch("{propertyId}/{listId}/{isOn}"), Authorize]
    public ActionResult<bool> Update(int propertyId, int listId, bool isOn)
    {
        // Do something
        return true;
    }
}

Кроме того, чтобы вернуть ошибку 401, когда пользователь не авторизован вместо перенаправления, я добавил следующий код в мой Startup учебный класс

services.ConfigureApplicationCookie(config =>
{
    config.Events = new CookieAuthenticationEvents
    {
        OnRedirectToLogin = ctx =>
        {
            if (ctx.Request.Path.StartsWithSegments("/api", StringComparison.CurrentCultureIgnoreCase))
            {
                ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            }
            else
            {
                ctx.Response.Redirect(ctx.RedirectUri);
            }

            return Task.FromResult(0);
        }
    };
});

Теперь, чтобы вызвать этот API с помощью jQuery Я сделал следующее

$('.update-property').click(function (e) {
    e.preventDefault();
    var obj = $(this);
    $.ajax({
        url: '/api/Categories/Update',
        type: 'PATCH',
        data: {
            'propertyId': obj.data('property-id'),
            'listId': obj.data('list-id'),
            'isOn': obj.data('is-on') === 'True' ? 'false' : 'true'
        },

        success: function (response) {

            console.log(response);

            // if response unauthorized, redirect to the login page with the ReturnUrl
            // else if response.data is true then change the icon
        }
    });
});

Но этот запрос продолжает возвращать код ошибки 404 http. Я проверил этот вопрос в инструментах разработчика и вижу, что параметр задан правильно, а URL действителен.

Как я могу правильно обработать этот запрос PATCH?

2 ответа

Решение
[Route("api/[controller]"), ApiController, Produces("application/json")]
public class CategoriesController : ControllerBase
{
    [HttpPatch("{propertyId}/{listId}/{isOn}"), Authorize]
    public ActionResult<bool> Update(int propertyId, int listId, bool isOn)

Шаблоны маршрутов здесь определяют URL для вашей конечной точки обновления. В этом случае результирующий шаблон URL будет таким:

api/Categories/{propertyId}/{listId}/{isOn}

Так, например, действительный URL для этой конечной точки будет /api/Categories/12/34/true,

Если вы не хотите передавать значения в качестве параметров (поскольку вы уже передаете их в теле), вам нужно изменить шаблон маршрута. Например, вы можете просто удалить шаблон маршрута в методе действия:

[HttpPatch, Authorize]
public ActionResult<bool> Update(int propertyId, int listId, bool isOn)
// …

Тогда URL будет просто api/Categories,

Конечно, вы могли бы также сделать api/Categories/Update URL для конечной точки, но с REST обычно не рекомендуется иметь имена методов в URL. Запрос PATCH обычно означает "обновить этот ресурс", и тогда вы будете указывать на URL-адрес ресурса.

Вам нужно отправить запрос с localhost:44313/api/Categories URL-адрес. Не ставьте префикс обновления. Вам просто нужно отправить запрос Patch на ваш localhost:44313/api/Categories конечная точка.

с параметрами

localhost:44313/api/Categories/{propertyId}/{listId}/{isOn}

Другие вопросы по тегам