ASP.NET Core Web API의 JsonPatch

이 문서에서는 ASP.NET Core 웹 API에서 JSON 패치 요청을 처리하는 방법을 설명합니다.

패키지 설치

ASP.NET Core 웹 API의 JSON 패치 지원은 Newtonsoft.Json을 기반으로 하며 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 패키지를 필요로 합니다. JSON 패치 지원을 사용하도록 설정하려면 다음을 수행합니다.

  • Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 패키지를 설치합니다.

  • AddNewtonsoftJson을 호출합니다. 예시:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllers()
        .AddNewtonsoftJson();
    
    var app = builder.Build();
    
    app.UseHttpsRedirection();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    

AddNewtonsoftJson모든JSON 콘텐츠의 형식을 지정하는 데 사용되는 System.Text.Json 기반 입력 및 출력 포맷터를 대체합니다. 이 확장 메서드는 다음 MVC 서비스 등록 방법과 호환됩니다.

JsonPatch를 사용하려면 헤더를 Content-Type .로 설정해야 합니다 application/json-patch+json.

System.Text.Json을 사용할 때 JSON 패치에 대한 지원 추가

System.Text.Json 기반 입력 포맷터는 JSON 패치를 지원하지 않습니다. 다른 입력 및 출력 포맷터를 변경하지 않고 Newtonsoft.Json를 사용하여 JSON 패치에 대한 지원을 추가하려면 다음을 수행합니다.

  • Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 패키지를 설치합니다.

  • 다음과 같이 Program.cs를 업데이트합니다.

    using JsonPatchSample;
    using Microsoft.AspNetCore.Mvc.Formatters;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllers(options =>
    {
        options.InputFormatters.Insert(0, MyJPIF.GetJsonPatchInputFormatter());
    });
    
    var app = builder.Build();
    
    app.UseHttpsRedirection();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Formatters;
    using Microsoft.Extensions.Options;
    
    namespace JsonPatchSample;
    
    public static class MyJPIF
    {
        public static NewtonsoftJsonPatchInputFormatter GetJsonPatchInputFormatter()
        {
            var builder = new ServiceCollection()
                .AddLogging()
                .AddMvc()
                .AddNewtonsoftJson()
                .Services.BuildServiceProvider();
    
            return builder
                .GetRequiredService<IOptions<MvcOptions>>()
                .Value
                .InputFormatters
                .OfType<NewtonsoftJsonPatchInputFormatter>()
                .First();
        }
    }
    

앞의 코드는 NewtonsoftJsonPatchInputFormatter 인스턴스를 만들고 MvcOptions.InputFormatters 컬렉션의 첫 번째 항목으로 삽입합니다. 이 등록 순서는 다음을 보장합니다.

  • NewtonsoftJsonPatchInputFormatter는 JSON 패치 요청을 처리합니다.
  • 기존 System.Text.Json 기반 입력 및 포맷터는 다른 모든 JSON 요청 및 응답을 처리합니다.

Newtonsoft.Json.JsonConvert.SerializeObject 메서드를 사용하여 JsonPatchDocument를 직렬화합니다.

PATCH HTTP 요청 메서드

PUT 및 PATCH 메서드는 기존 리소스를 업데이트하는 데 사용됩니다. 두 메서드의 차이점은 PUT은 전체 리소스를 바꾸지만, PATCH는 변경 내용만 지정한다는 것입니다.

JSON 패치

JSON 패치는 리소스에 적용할 업데이트를 지정하기 위한 형식입니다. JSON 패치 문서에는 작업 배열이 있습니다. 각 작업은 특정 유형의 변경 내용을 식별합니다. 이러한 변경의 예제로는 배열 요소 추가 또는 속성 값 바꾸기가 있습니다.

예를 들어 다음 JSON 문서는 리소스, 리소스의 JSON 패치 문서 및 패치 작업을 적용한 결과를 나타냅니다.

리소스 예제

{
  "customerName": "John",
  "orders": [
    {
      "orderName": "Order0",
      "orderType": null
    },
    {
      "orderName": "Order1",
      "orderType": null
    }
  ]
}

JSON 패치 예제

[
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

위의 JSON에서

  • op 속성은 작업 형식을 나타냅니다.
  • path 속성은 업데이트할 요소를 나타냅니다.
  • value 속성은 새 값을 제공합니다.

패치 후 리소스

앞의 JSON 패치 문서를 적용한 후 리소스는 다음과 같습니다.

{
  "customerName": "Barry",
  "orders": [
    {
      "orderName": "Order0",
      "orderType": null
    },
    {
      "orderName": "Order1",
      "orderType": null
    },
    {
      "orderName": "Order2",
      "orderType": null
    }
  ]
}

JSON 패치 문서를 리소스에 적용하여 변경한 내용은 원자성입니다. 목록에서 작업이 실패하면 목록의 작업이 적용되지 않습니다.

경로 구문

작업 개체의 path 속성에서 수준 사이에는 슬래시가 있습니다. 예: "/address/zipCode".

0부터 시작하는 인덱스는 배열 요소를 지정하는 데 사용됩니다. addresses 배열의 첫 번째 요소는 /addresses/0에 있습니다. 배열 끝에 add(추가)하려면 인덱스 번호가 아닌 하이픈(-)을 사용합니다(/addresses/-).

작업

다음 테이블에서는 JSON 패치 사양에 정의된 지원되는 작업을 보여 줍니다.

연산 주의
add 속성 또는 배열 요소를 추가합니다. 기존 속성의 경우 값을 설정합니다.
remove 속성 또는 배열 요소를 제거합니다.
replace 동일한 위치에서 add가 뒤에 오는 remove와 같습니다.
move 소스의 값을 사용하는 대상에 대한 add가 뒤에 오는 소스에서 remove와 같습니다.
copy 소스의 값을 사용하는 대상에 대한 add와 같습니다.
test path의 값이 제공된 value와 같은 경우 성공 상태 코드를 반환합니다.

ASP.NET Core의 JSON 패치

JSON 패치의 ASP.NET Core 구현은 Microsoft.AspNetCore.JsonPatch NuGet 패키지로 제공됩니다.

작업 메서드 코드

API 컨트롤러에서 JSON 패치의 작업 메서드는 다음과 같습니다.

예를 들면 다음과 같습니다.

[HttpPatch]
public IActionResult JsonPatchWithModelState(
    [FromBody] JsonPatchDocument<Customer> patchDoc)
{
    if (patchDoc != null)
    {
        var customer = CreateCustomer();

        patchDoc.ApplyTo(customer, ModelState);

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

        return new ObjectResult(customer);
    }
    else
    {
        return BadRequest(ModelState);
    }
}

샘플 앱의 이 코드는 다음 Customer 모델에서 작동합니다.

namespace JsonPatchSample.Models;

public class Customer
{
    public string? CustomerName { get; set; }
    public List<Order>? Orders { get; set; }
}
namespace JsonPatchSample.Models;

public class Order
{
    public string OrderName { get; set; }
    public string OrderType { get; set; }
}

샘플 작업 메서드:

  • Customer를 생성합니다.
  • 패치를 적용합니다.
  • 응답의 본문으로 결과를 반환합니다.

실제 앱에서 이 코드는 데이터베이스와 같은 저장소에서 데이터를 검색하고 패치를 적용한 후 데이터베이스를 업데이트합니다.

모델 상태

앞의 작업 메서드 예제에서는 모델 상태를 매개 변수 중 하나로 가져오는 ApplyTo의 오버로드를 호출합니다. 이 옵션을 사용하여 응답으로 오류 메시지를 가져올 수 있습니다. 다음 예제에서는 test 작업에 대한 400 잘못된 요청 응답의 본문을 보여 줍니다.

{
  "Customer": [
    "The current value 'John' at path 'customerName' != test value 'Nancy'."
  ]
}

동적 개체

다음 작업 메서드 예제에서는 동적 개체에 패치를 적용하는 방법을 보여 줍니다.

[HttpPatch]
public IActionResult JsonPatchForDynamic([FromBody]JsonPatchDocument patch)
{
    dynamic obj = new ExpandoObject();
    patch.ApplyTo(obj);

    return Ok(obj);
}

추가 작업

  • path가 배열 요소를 가리키는 경우: path에 지정된 요소 앞에 새 요소를 삽입합니다.
  • path가 속성을 가리키는 경우: 속성 값을 설정합니다.
  • 존재하지 않는 위치를 가리키는 경우 path :
    • 패치할 리소스가 동적 개체인 경우: 속성을 추가합니다.
    • 패치할 리소스가 정적 개체인 경우: 요청이 실패합니다.

다음 샘플 패치 문서는 CustomerName의 값을 설정하고 Order 개체를 Orders 배열 끝에 추가합니다.

[
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

제거 작업

  • path가 배열 요소를 가리키는 경우: 요소를 제거합니다.
  • 속성을 가리키는 경우 path :
    • 패치할 리소스가 동적 개체인 경우: 속성을 제거합니다.
    • 패치할 리소스가 정적 개체인 경우:
      • 속성이 nullable인 경우: null로 설정합니다.
      • 속성이 nullable이 아닌 경우: default<T>로 설정합니다.

다음 샘플 패치 문서는 CustomerName을 null로 설정하고 Orders[0]를 삭제합니다.

[
  {
    "op": "remove",
    "path": "/customerName"
  },
  {
    "op": "remove",
    "path": "/orders/0"
  }
]

바꾸기 작업

이 작업은 add가 뒤에 오는 remove와 기능적으로 동일합니다.

다음 샘플 패치 문서는 CustomerName의 값을 설정하고 Orders[0]를 새 Order 개체로 바꿉니다.

[
  {
    "op": "replace",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "replace",
    "path": "/orders/0",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

이동 작업

  • path가 배열 요소를 가리키는 경우: from 요소를 path 요소 위치에 복사한 후 from 요소에서 remove 작업을 실행합니다.
  • path가 속성을 가리키는 경우: from 속성 값을 path 속성에 복사한 후 from 속성에서 remove 작업을 실행합니다.
  • 존재하지 않는 속성을 가리키는 경우 path :
    • 패치할 리소스가 정적 개체인 경우: 요청이 실패합니다.
    • 패치할 리소스가 동적 개체인 경우: from 속성을 path에 지정된 위치로 복사한 후 from 속성에서 remove 작업을 실행합니다.

다음 샘플 패치 문서는 다음을 수행합니다.

  • Orders[0].OrderName 값을 CustomerName에 복사합니다.
  • Orders[0].OrderName을 null로 설정합니다.
  • Orders[1]Orders[0] 앞으로 이동합니다.
[
  {
    "op": "move",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "move",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

복사 작업

이 작업은 마지막 remove 단계 없이 move 작업과 기능적으로 동일합니다.

다음 샘플 패치 문서는 다음을 수행합니다.

  • Orders[0].OrderName 값을 CustomerName에 복사합니다.
  • Orders[1] 복사본을 Orders[0] 앞에 삽입합니다.
[
  {
    "op": "copy",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "copy",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

테스트 작업

path에 지정된 위치의 값이 value에 제공된 값과 다른 경우 요청이 실패합니다. 이 경우 패치 문서의 다른 모든 작업이 성공하더라도 전체 PATCH 요청이 실패합니다.

test 작업은 일반적으로 동시성 충돌이 발생하는 경우 업데이트를 방지하는 데 사용됩니다.

CustomerName의 초기 값이 “John”인 경우 테스트에 실패하므로 다음 샘플 패치 문서는 영향을 주지 않습니다.

[
  {
    "op": "test",
    "path": "/customerName",
    "value": "Nancy"
  },
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  }
]

코드 가져오기

샘플 코드 보기 또는 다운로드 (다운로드하는 방법)

샘플을 테스트하려면 앱을 실행하고 다음 설정을 사용하여 HTTP 요청을 보냅니다.

  • URL: http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate
  • HTTP 메서드: PATCH
  • 헤더: Content-Type: application/json-patch+json
  • 본문: JSON 프로젝트 폴더에서 JSON 패치 문서 샘플 중 하나를 복사하여 붙여넣습니다.

추가 리소스

이 문서에서는 ASP.NET Core 웹 API에서 JSON 패치 요청을 처리하는 방법을 설명합니다.

패키지 설치

앱에서 JSON 패치 지원을 사용하도록 설정하려면 다음 단계를 완료합니다.

  1. Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 패키지를 설치합니다.

  2. 프로젝트의 Startup.ConfigureServices 메서드를 업데이트하여 AddNewtonsoftJson을 호출합니다. 예시:

    services
        .AddControllersWithViews()
        .AddNewtonsoftJson();
    

AddNewtonsoftJson은 MVC 서비스 등록 메서드

JSON Patch, AddNewtonsoftJson 및 System.Text.Json과 호환됩니다.

AddNewtonsoftJson모든JSON 콘텐츠의 형식을 지정하는 데 사용되는 System.Text.Json 기반 입력 및 출력 포맷터를 대체합니다. Newtonsoft.Json을 사용하여 JSON 패치 지원을 추가하지만 다른 포맷터를 변경하지 않으려면 프로젝트의 Startup.ConfigureServices 메서드를 다음과 같이 업데이트합니다.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        options.InputFormatters.Insert(0, GetJsonPatchInputFormatter());
    });
}

private static NewtonsoftJsonPatchInputFormatter GetJsonPatchInputFormatter()
{
    var builder = new ServiceCollection()
        .AddLogging()
        .AddMvc()
        .AddNewtonsoftJson()
        .Services.BuildServiceProvider();

    return builder
        .GetRequiredService<IOptions<MvcOptions>>()
        .Value
        .InputFormatters
        .OfType<NewtonsoftJsonPatchInputFormatter>()
        .First();
}

위의 코드에는 Microsoft.AspNetCore.Mvc.NewtonsoftJson 패키지와 다음 using 문이 필요합니다.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Linq;

Newtonsoft.Json.JsonConvert.SerializeObject 메서드를 사용하여 JsonPatchDocument를 직렬화합니다.

PATCH HTTP 요청 메서드

PUT 및 PATCH 메서드는 기존 리소스를 업데이트하는 데 사용됩니다. 두 메서드의 차이점은 PUT은 전체 리소스를 바꾸지만, PATCH는 변경 내용만 지정한다는 것입니다.

JSON 패치

JSON 패치는 리소스에 적용할 업데이트를 지정하기 위한 형식입니다. JSON 패치 문서에는 작업 배열이 있습니다. 각 작업은 특정 유형의 변경 내용을 식별합니다. 이러한 변경의 예제로는 배열 요소 추가 또는 속성 값 바꾸기가 있습니다.

예를 들어 다음 JSON 문서는 리소스, 리소스의 JSON 패치 문서 및 패치 작업을 적용한 결과를 나타냅니다.

리소스 예제

{
  "customerName": "John",
  "orders": [
    {
      "orderName": "Order0",
      "orderType": null
    },
    {
      "orderName": "Order1",
      "orderType": null
    }
  ]
}

JSON 패치 예제

[
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

위의 JSON에서

  • op 속성은 작업 형식을 나타냅니다.
  • path 속성은 업데이트할 요소를 나타냅니다.
  • value 속성은 새 값을 제공합니다.

패치 후 리소스

앞의 JSON 패치 문서를 적용한 후 리소스는 다음과 같습니다.

{
  "customerName": "Barry",
  "orders": [
    {
      "orderName": "Order0",
      "orderType": null
    },
    {
      "orderName": "Order1",
      "orderType": null
    },
    {
      "orderName": "Order2",
      "orderType": null
    }
  ]
}

JSON 패치 문서를 리소스에 적용하여 변경한 내용은 원자성입니다. 목록에서 작업이 실패하면 목록의 작업이 적용되지 않습니다.

경로 구문

작업 개체의 path 속성에서 수준 사이에는 슬래시가 있습니다. 예: "/address/zipCode".

0부터 시작하는 인덱스는 배열 요소를 지정하는 데 사용됩니다. addresses 배열의 첫 번째 요소는 /addresses/0에 있습니다. 배열 끝에 add(추가)하려면 인덱스 번호가 아닌 하이픈(-)을 사용합니다(/addresses/-).

작업

다음 테이블에서는 JSON 패치 사양에 정의된 지원되는 작업을 보여 줍니다.

연산 주의
add 속성 또는 배열 요소를 추가합니다. 기존 속성의 경우 값을 설정합니다.
remove 속성 또는 배열 요소를 제거합니다.
replace 동일한 위치에서 add가 뒤에 오는 remove와 같습니다.
move 소스의 값을 사용하는 대상에 대한 add가 뒤에 오는 소스에서 remove와 같습니다.
copy 소스의 값을 사용하는 대상에 대한 add와 같습니다.
test path의 값이 제공된 value와 같은 경우 성공 상태 코드를 반환합니다.

ASP.NET Core의 JSON 패치

JSON 패치의 ASP.NET Core 구현은 Microsoft.AspNetCore.JsonPatch NuGet 패키지로 제공됩니다.

작업 메서드 코드

API 컨트롤러에서 JSON 패치의 작업 메서드는 다음과 같습니다.

  • HttpPatch 특성을 사용하여 주석으로 처리됩니다.
  • 일반적으로 [FromBody]를 사용하여 JsonPatchDocument<T>를 수락합니다.
  • 패치 문서에서 ApplyTo를 호출하여 변경 내용을 적용합니다.

예를 들면 다음과 같습니다.

[HttpPatch]
public IActionResult JsonPatchWithModelState(
    [FromBody] JsonPatchDocument<Customer> patchDoc)
{
    if (patchDoc != null)
    {
        var customer = CreateCustomer();

        patchDoc.ApplyTo(customer, ModelState);

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

        return new ObjectResult(customer);
    }
    else
    {
        return BadRequest(ModelState);
    }
}

샘플 앱의 이 코드는 다음 Customer 모델에서 작동합니다.

using System.Collections.Generic;

namespace JsonPatchSample.Models
{
    public class Customer
    {
        public string CustomerName { get; set; }
        public List<Order> Orders { get; set; }
    }
}
namespace JsonPatchSample.Models
{
    public class Order
    {
        public string OrderName { get; set; }
        public string OrderType { get; set; }
    }
}

샘플 작업 메서드:

  • Customer를 생성합니다.
  • 패치를 적용합니다.
  • 응답의 본문으로 결과를 반환합니다.

실제 앱에서 이 코드는 데이터베이스와 같은 저장소에서 데이터를 검색하고 패치를 적용한 후 데이터베이스를 업데이트합니다.

모델 상태

앞의 작업 메서드 예제에서는 모델 상태를 매개 변수 중 하나로 가져오는 ApplyTo의 오버로드를 호출합니다. 이 옵션을 사용하여 응답으로 오류 메시지를 가져올 수 있습니다. 다음 예제에서는 test 작업에 대한 400 잘못된 요청 응답의 본문을 보여 줍니다.

{
    "Customer": [
        "The current value 'John' at path 'customerName' is not equal to the test value 'Nancy'."
    ]
}

동적 개체

다음 작업 메서드 예제에서는 동적 개체에 패치를 적용하는 방법을 보여 줍니다.

[HttpPatch]
public IActionResult JsonPatchForDynamic([FromBody]JsonPatchDocument patch)
{
    dynamic obj = new ExpandoObject();
    patch.ApplyTo(obj);

    return Ok(obj);
}

추가 작업

  • path가 배열 요소를 가리키는 경우: path에 지정된 요소 앞에 새 요소를 삽입합니다.
  • path가 속성을 가리키는 경우: 속성 값을 설정합니다.
  • 존재하지 않는 위치를 가리키는 경우 path :
    • 패치할 리소스가 동적 개체인 경우: 속성을 추가합니다.
    • 패치할 리소스가 정적 개체인 경우: 요청이 실패합니다.

다음 샘플 패치 문서는 CustomerName의 값을 설정하고 Order 개체를 Orders 배열 끝에 추가합니다.

[
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

제거 작업

  • path가 배열 요소를 가리키는 경우: 요소를 제거합니다.
  • 속성을 가리키는 경우 path :
    • 패치할 리소스가 동적 개체인 경우: 속성을 제거합니다.
    • 패치할 리소스가 정적 개체인 경우:
      • 속성이 nullable인 경우: null로 설정합니다.
      • 속성이 nullable이 아닌 경우: default<T>로 설정합니다.

다음 샘플 패치 문서는 CustomerName을 null로 설정하고 Orders[0]를 삭제합니다.

[
  {
    "op": "remove",
    "path": "/customerName"
  },
  {
    "op": "remove",
    "path": "/orders/0"
  }
]

바꾸기 작업

이 작업은 add가 뒤에 오는 remove와 기능적으로 동일합니다.

다음 샘플 패치 문서는 CustomerName의 값을 설정하고 Orders[0]를 새 Order 개체로 바꿉니다.

[
  {
    "op": "replace",
    "path": "/customerName",
    "value": "Barry"
  },
  {
    "op": "replace",
    "path": "/orders/0",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }
  }
]

이동 작업

  • path가 배열 요소를 가리키는 경우: from 요소를 path 요소 위치에 복사한 후 from 요소에서 remove 작업을 실행합니다.
  • path가 속성을 가리키는 경우: from 속성 값을 path 속성에 복사한 후 from 속성에서 remove 작업을 실행합니다.
  • 존재하지 않는 속성을 가리키는 경우 path :
    • 패치할 리소스가 정적 개체인 경우: 요청이 실패합니다.
    • 패치할 리소스가 동적 개체인 경우: from 속성을 path에 지정된 위치로 복사한 후 from 속성에서 remove 작업을 실행합니다.

다음 샘플 패치 문서는 다음을 수행합니다.

  • Orders[0].OrderName 값을 CustomerName에 복사합니다.
  • Orders[0].OrderName을 null로 설정합니다.
  • Orders[1]Orders[0] 앞으로 이동합니다.
[
  {
    "op": "move",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "move",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

복사 작업

이 작업은 마지막 remove 단계 없이 move 작업과 기능적으로 동일합니다.

다음 샘플 패치 문서는 다음을 수행합니다.

  • Orders[0].OrderName 값을 CustomerName에 복사합니다.
  • Orders[1] 복사본을 Orders[0] 앞에 삽입합니다.
[
  {
    "op": "copy",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "copy",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

테스트 작업

path에 지정된 위치의 값이 value에 제공된 값과 다른 경우 요청이 실패합니다. 이 경우 패치 문서의 다른 모든 작업이 성공하더라도 전체 PATCH 요청이 실패합니다.

test 작업은 일반적으로 동시성 충돌이 발생하는 경우 업데이트를 방지하는 데 사용됩니다.

CustomerName의 초기 값이 “John”인 경우 테스트에 실패하므로 다음 샘플 패치 문서는 영향을 주지 않습니다.

[
  {
    "op": "test",
    "path": "/customerName",
    "value": "Nancy"
  },
  {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"
  }
]

코드 가져오기

샘플 코드 보기 또는 다운로드 (다운로드하는 방법)

샘플을 테스트하려면 앱을 실행하고 다음 설정을 사용하여 HTTP 요청을 보냅니다.

  • URL: http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate
  • HTTP 메서드: PATCH
  • 헤더: Content-Type: application/json-patch+json
  • 본문: JSON 프로젝트 폴더에서 JSON 패치 문서 샘플 중 하나를 복사하여 붙여넣습니다.

추가 리소스