JsonPatch in ASP.NET Core-Web-API

In diesem Artikel wird erläutert, wie JSON Patch-Anforderungen in einer ASP.NET Core-Web-API behandelt werden.

Paketinstallation

JSOn Patch-Unterstützung in der ASP.NET Core-Web-API basiert auf Newtonsoft.Json und erfordert das Microsoft.AspNetCore.Mvc.NewtonsoftJson-NuGet-Paket. So aktivieren Sie JSON Patch-Unterstützung:

  • Installieren Sie das Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet-Paket.

  • Rufen Sie AddNewtonsoftJson auf. Beispiel:

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

AddNewtonsoftJson ersetzt die auf System.Text.Json basierenden Eingabe- und Ausgabestandardformatierer, die für die Formatierung allerJSON-Inhalte verwendet werden. Diese Erweiterungsmethode ist mit den folgenden MVC-Dienstregistrierungsmethoden kompatibel:

JsonPatch erfordert das Festlegen des Content-Type-Headers auf application/json-patch+json.

Hinzufügen von Unterstützung für JSON Patch bei Verwendung von System.Text.Json

Der System.Text.Json-basierte Eingabeformatierer unterstützt JSON Patch nicht. So fügen Sie Unterstützung für JSON Patch mit Newtonsoft.Json hinzu, während die anderen Eingabe- und Ausgabeformatierer unverändert bleiben:

  • Installieren Sie das Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet-Paket.

  • Aktualisieren Sie 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();
        }
    }
    

Der Code oben erstellt eine Instanz von NewtonsoftJsonPatchInputFormatter und fügt sie als ersten Eintrag in der MvcOptions.InputFormatters-Sammlung ein. Durch diese Reihenfolge der Registrierung wird Folgendes sichergestellt:

  • NewtonsoftJsonPatchInputFormatter verarbeitet JSON Patch-Anforderungen.
  • Die vorhandenen System.Text.Json-basierten Eingabe- und Formatierer verarbeiten alle anderen JSON-Anforderungen und -Antworten.

Verwenden Sie die Newtonsoft.Json.JsonConvert.SerializeObject-Methode zum Serialisieren eines JsonPatchDocument.

PATCH HTTP-Anforderungsmethode

Die Methoden PUT und PATCH werden verwendet, um eine vorhandene Ressource zu aktualisieren. Der Unterschied zwischen den beiden Methoden besteht darin, dass PUT die gesamte Ressource ersetzt, während PATCH nur die Änderungen angibt.

JSON Patch

Mit dem JSON Patch-Format geben Sie an, dass Updates auf eine Ressource angewendet werden sollen. Ein JSON Patch-Dokument verfügt über ein Array von Vorgängen. Jeder Vorgang identifiziert einen bestimmten Änderungstyp. Beispiele für solche Änderungen sind das Hinzufügen eines Arrayelements oder das Ersetzen eines Eigenschaftswerts.

Die folgenden JSON-Dokumente stellen beispielsweise eine Ressource, ein JSON Patch-Dokument für die Ressource und das Ergebnis der Anwendung der Patchvorgänge dar.

Ressourcenbeispiel

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

JSON Patch-Beispiel

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

Für den JSON oben gilt:

  • Die op-Eigenschaft gibt den Typ des Vorgangs an.
  • Die path-Eigenschaft gibt das zu aktualisierende Element an.
  • Die value-Eigenschaft stellt den neuen Wert bereit.

Ressource nach dem Patch

So sieht die Ressource nach der Anwendung des voranstehenden JSON Patch-Dokuments aus:

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

Die Änderungen, die durch Anwenden eines JSON Patch-Dokuments auf eine Ressource vorgenommen werden, sind atomisch. Wenn ein Vorgang aus der Liste fehlschlägt, wird kein Vorgang aus der Liste angewendet.

Pfadsyntax

Die path-Eigenschaft eines Vorgangsobjekts weist Schrägstriche zwischen Ebenen auf. Beispiel: "/address/zipCode".

Nullbasierte Indizes werden verwendet, um Arrayelemente anzugeben. Das erste Element des addresses-Arrays wäre bei /addresses/0. Zum add ans Ende eines Arrays verwenden Sie einen Bindestrich (-) anstelle einer Indexnummer: /addresses/-.

Operationen (Operations)

Die folgende Tabelle zeigt unterstützt Vorgänge gemäß der JSON Patch-Spezifikation:

Vorgang Hinweise
add Hinzufügen einer Eigenschaft oder eines Arrayelements. Für vorhandene Eigenschaft: set value.
remove Entfernen einer Eigenschaft oder eines Arrayelements.
replace Identisch mit remove, gefolgt von add an gleicher Stelle.
move Identisch mit remove aus der Quelle, gefolgt von add zum Ziel unter Verwendung des Werts aus der Quelle.
copy Identisch mit add zum Ziel unter Verwendung des Werts aus der Quelle.
test Gibt Statuscode für Erfolg zurück, wenn der Wert von path = bereitgestellter value.

JSON Patch in ASP.NET Core

Die ASP.NET Core-Implementierung von JSON Patch wird im Microsoft.AspNetCore.JsonPatch-NuGet-Paket bereitgestellt.

Aktionsmethodencode

Eine Aktionsmethode für JSON Patch in einem API-Controller:

Hier sehen Sie ein Beispiel:

[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);
    }
}

Dieser Code aus der Beispiel-App funktioniert mit dem folgenden Customer-Modell:

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; }
}

Die Beispielaktionsmethode:

  • Erstellt ein Objekt vom Typ Customer.
  • Wendet den Patch an.
  • Gibt das Ergebnis wird im Textkörper der Antwort zurück.

In einer realen App würde der Code die Daten aus einem Speicher wie z.B. einer Datenbank abrufen und die Datenbank nach dem Anwenden des Patchs aktualisieren.

Modellstatus

Das voranstehende Aktionsmethodenbeispiel ruft eine Überladung von ApplyTo auf, die den Modellstatus als einen seiner Parameter akzeptiert. Mit dieser Option können Sie Fehlermeldungen in Antworten abrufen. Das folgende Beispiel zeigt den Textkörper einer „400 (Ungültige Anforderung)-Antwort für einen test Vorgang:

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

Dynamische Objekte

Das folgende Aktionsmethodenbeispiel veranschaulicht das Anwenden ein Patches auf ein dynamisches Objekt:

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

    return Ok(obj);
}

Add-Vorgang (Hinzufügen)

  • Wenn path auf ein Arrayelement verweist: Fügt ein neues Element vor dem von path angegebenen Element ein.
  • Wenn path auf eine Eigenschaft verweist: Legt den Eigenschaftswert fest.
  • Wenn path auf einen nicht vorhandenen Speicherort verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein dynamisches Objekt ist: Fügt eine Eigenschaft hinzu.
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist: Die Anforderung schlägt fehl.

Das folgende Patch-Dokumentbeispiel legt den Wert von CustomerName fest und fügt ein Order-Objekt am Ende des Orders-Arrays hinzu.

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

Remove-Vorgang (Entfernen)

  • Wenn path auf ein Arrayelement verweist: Entfernt das Element.
  • Wenn path auf eine Eigenschaft verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein dynamisches Objekt ist: Entfernt die Eigenschaft.
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist:
      • Wenn die Eigenschaft NULL-Werte zulässt: auf Null festlegen.
      • Wenn die Eigenschaft keine NULL-Werte zulässt: auf default<T> festlegen.

Im folgenden Beispiel legt das Patch-Dokument CustomerName auf Null fest und löscht Orders[0]:

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

Replace-Vorgang (Ersetzen)

Dieser Vorgang ist funktionell identisch mit einem remove, gefolgt von einem add.

Das folgende Patch-Dokumentbeispiel legt den Wert von CustomerName fest und ersetzt Orders[0] durch ein neues Order-Objekt:

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

Move-Vorgang (Verschieben)

  • Wenn path auf ein Arrayelement verweist: Kopiert das from-Element an den Speicherort des path-Elements und führt dann einen remove-Vorgang für das from-Element aus.
  • Wenn path auf eine Eigenschaft verweist: Kopiert den Wert der from-Eigenschaft in die path-Eigenschaft, und führt dann einen remove-Vorgang für die from-Eigenschaft aus.
  • Wenn path auf eine nicht vorhandene Eigenschaft verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist: Die Anforderung schlägt fehl.
    • Wenn es sich bei der Ressource, die gepatcht werden soll, um ein dynamisches Objekt handelt: Kopiert die from-Eigenschaft in den von path angegebenen Speicherort, und führt dann einen remove-Vorgang für die from-Eigenschaft aus.

Das folgende Patch-Dokumentbeispiel:

  • Kopiert den Wert der Orders[0].OrderName nach CustomerName.
  • Legt Orders[0].OrderName auf Null fest.
  • Verschiebt Orders[1] vor Orders[0].
[
  {
    "op": "move",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "move",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

Copy-Vorgang (Kopieren)

Dieser Vorgang ist funktionell identisch mit einem move-Vorgang ohne den abschließenden remove-Schritt.

Das folgende Patch-Dokumentbeispiel:

  • Kopiert den Wert der Orders[0].OrderName nach CustomerName.
  • Fügt eine Kopie von Orders[1] vor Orders[0] ein.
[
  {
    "op": "copy",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "copy",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

Test-Vorgang (Testen)

Wenn der Wert an dem von path angegebenen Speicherort sich von dem in value bereitgestellten Wert unterscheidet, schlägt die Anforderung fehl. In diesem Fall schlägt die gesamte PATCH-Anforderung fehl, selbst wenn alle anderen Vorgänge im Patch-Dokument ansonsten erfolgreich ausgeführt werden könnten.

Der test-Vorgang wird häufig verwendet, um ein Update zu verhindern, wenn ein Parallelitätskonflikt vorhanden ist.

Das folgende Patch-Dokumentbeispiel hat keine Auswirkungen, wenn der Anfangswert von CustomerName „John“ ist, da der Test fehlschlägt:

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

Abrufen des Codes

Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen)

Um das Beispiel zu testen, führen Sie die App aus, und senden Sie HTTP-Anforderungen mit den folgenden Einstellungen:

  • URL: http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate
  • HTTP-Methode: PATCH
  • Header: Content-Type: application/json-patch+json
  • Textkörper: Kopieren und Einfügen eines der JSON-Patch-Dokumentbeispiele aus dem JSON-Projektordner.

Zusätzliche Ressourcen

In diesem Artikel wird erläutert, wie JSON Patch-Anforderungen in einer ASP.NET Core-Web-API behandelt werden.

Paketinstallation

Führen Sie die folgenden Schritte aus, um JSON Patch-Unterstützung in Ihrer App zu aktivieren:

  1. Installieren Sie das Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet-Paket.

  2. Aktualisieren Sie die Startup.ConfigureServices-Methode des Projekts so, dass diese AddNewtonsoftJson aufruft. Beispiel:

    services
        .AddControllersWithViews()
        .AddNewtonsoftJson();
    

AddNewtonsoftJson ist mit den folgenden MVC-Dienstregistrierungsmethoden kompatibel:

JSON Patch, AddNewtonsoftJson und System.Text.Json

AddNewtonsoftJson ersetzt die auf System.Text.Json basierenden Eingabe- und Ausgabeformatierer, die für die Formatierung allerJSON-Inhalte verwendet werden. Um Unterstützung für JSON Patch mit Newtonsoft.Json hinzuzufügen, während die anderen Formatierer unverändert bleiben, aktualisieren Sie die Startup.ConfigureServices-Methode des Projekts wie folgt:

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();
}

Der vorangehende Code erfordert das Paket Microsoft.AspNetCore.Mvc.NewtonsoftJson und die folgenden using-Anweisungen:

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;

Verwenden Sie die Newtonsoft.Json.JsonConvert.SerializeObject-Methode, um ein JsonPatchDocument zu serialisieren.

PATCH HTTP-Anforderungsmethode

Die Methoden PUT und PATCH werden verwendet, um eine vorhandene Ressource zu aktualisieren. Der Unterschied zwischen den beiden Methoden besteht darin, dass PUT die gesamte Ressource ersetzt, während PATCH nur die Änderungen angibt.

JSON Patch

Mit dem JSON Patch-Format geben Sie an, dass Updates auf eine Ressource angewendet werden sollen. Ein JSON Patch-Dokument verfügt über ein Array von Vorgängen. Jeder Vorgang identifiziert einen bestimmten Änderungstyp. Beispiele für solche Änderungen sind das Hinzufügen eines Arrayelements oder das Ersetzen eines Eigenschaftswerts.

Die folgenden JSON-Dokumente stellen beispielsweise eine Ressource, ein JSON Patch-Dokument für die Ressource und das Ergebnis der Anwendung der Patchvorgänge dar.

Ressourcenbeispiel

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

JSON Patch-Beispiel

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

Für den JSON oben gilt:

  • Die op-Eigenschaft gibt den Typ des Vorgangs an.
  • Die path-Eigenschaft gibt das zu aktualisierende Element an.
  • Die value-Eigenschaft stellt den neuen Wert bereit.

Ressource nach dem Patch

So sieht die Ressource nach der Anwendung des voranstehenden JSON Patch-Dokuments aus:

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

Die Änderungen, die durch Anwenden eines JSON Patch-Dokuments auf eine Ressource vorgenommen werden, sind atomisch. Wenn ein Vorgang aus der Liste fehlschlägt, wird kein Vorgang aus der Liste angewendet.

Pfadsyntax

Die path-Eigenschaft eines Vorgangsobjekts weist Schrägstriche zwischen Ebenen auf. Beispiel: "/address/zipCode".

Nullbasierte Indizes werden verwendet, um Arrayelemente anzugeben. Das erste Element des addresses-Arrays wäre bei /addresses/0. Zum add ans Ende eines Arrays verwenden Sie einen Bindestrich (-) anstelle einer Indexnummer: /addresses/-.

Operationen (Operations)

Die folgende Tabelle zeigt unterstützt Vorgänge gemäß der JSON Patch-Spezifikation:

Vorgang Hinweise
add Hinzufügen einer Eigenschaft oder eines Arrayelements. Für vorhandene Eigenschaft: set value.
remove Entfernen einer Eigenschaft oder eines Arrayelements.
replace Identisch mit remove, gefolgt von add an gleicher Stelle.
move Identisch mit remove aus der Quelle, gefolgt von add zum Ziel unter Verwendung des Werts aus der Quelle.
copy Identisch mit add zum Ziel unter Verwendung des Werts aus der Quelle.
test Gibt Statuscode für Erfolg zurück, wenn der Wert von path = bereitgestellter value.

JSON Patch in ASP.NET Core

Die ASP.NET Core-Implementierung von JSON Patch wird im Microsoft.AspNetCore.JsonPatch-NuGet-Paket bereitgestellt.

Aktionsmethodencode

Eine Aktionsmethode für JSON Patch in einem API-Controller:

  • Ist versehen mit dem HttpPatch-Attribut.
  • Akzeptiert eine JsonPatchDocument<T>-Klasse, in der Regel mit [FromBody].
  • Ruft ApplyTo für das Patch-Dokument auf, um die Änderungen anzuwenden.

Hier sehen Sie ein Beispiel:

[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);
    }
}

Dieser Code aus der Beispiel-App funktioniert mit dem folgenden Customer-Modell:

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; }
    }
}

Die Beispielaktionsmethode:

  • Erstellt ein Objekt vom Typ Customer.
  • Wendet den Patch an.
  • Gibt das Ergebnis wird im Textkörper der Antwort zurück.

In einer realen App würde der Code die Daten aus einem Speicher wie z.B. einer Datenbank abrufen und die Datenbank nach dem Anwenden des Patchs aktualisieren.

Modellstatus

Das voranstehende Aktionsmethodenbeispiel ruft eine Überladung von ApplyTo auf, die den Modellstatus als einen seiner Parameter akzeptiert. Mit dieser Option können Sie Fehlermeldungen in Antworten abrufen. Das folgende Beispiel zeigt den Textkörper einer „400 (Ungültige Anforderung)-Antwort für einen test Vorgang:

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

Dynamische Objekte

Das folgende Aktionsmethodenbeispiel veranschaulicht das Anwenden ein Patches auf ein dynamisches Objekt:

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

    return Ok(obj);
}

Add-Vorgang (Hinzufügen)

  • Wenn path auf ein Arrayelement verweist: Fügt ein neues Element vor dem von path angegebenen Element ein.
  • Wenn path auf eine Eigenschaft verweist: Legt den Eigenschaftswert fest.
  • Wenn path auf einen nicht vorhandenen Speicherort verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein dynamisches Objekt ist: Fügt eine Eigenschaft hinzu.
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist: Die Anforderung schlägt fehl.

Das folgende Patch-Dokumentbeispiel legt den Wert von CustomerName fest und fügt ein Order-Objekt am Ende des Orders-Arrays hinzu.

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

Remove-Vorgang (Entfernen)

  • Wenn path auf ein Arrayelement verweist: Entfernt das Element.
  • Wenn path auf eine Eigenschaft verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein dynamisches Objekt ist: Entfernt die Eigenschaft.
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist:
      • Wenn die Eigenschaft NULL-Werte zulässt: auf Null festlegen.
      • Wenn die Eigenschaft keine NULL-Werte zulässt: auf default<T> festlegen.

Im folgenden Beispiel legt das Patch-Dokument CustomerName auf Null fest und löscht Orders[0]:

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

Replace-Vorgang (Ersetzen)

Dieser Vorgang ist funktionell identisch mit einem remove, gefolgt von einem add.

Das folgende Patch-Dokumentbeispiel legt den Wert von CustomerName fest und ersetzt Orders[0] durch ein neues Order-Objekt:

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

Move-Vorgang (Verschieben)

  • Wenn path auf ein Arrayelement verweist: Kopiert das from-Element an den Speicherort des path-Elements und führt dann einen remove-Vorgang für das from-Element aus.
  • Wenn path auf eine Eigenschaft verweist: Kopiert den Wert der from-Eigenschaft in die path-Eigenschaft, und führt dann einen remove-Vorgang für die from-Eigenschaft aus.
  • Wenn path auf eine nicht vorhandene Eigenschaft verweist:
    • Wenn die Ressource, auf die der Patch angewendet werden soll, ein statisches Objekt ist: Die Anforderung schlägt fehl.
    • Wenn es sich bei der Ressource, die gepatcht werden soll, um ein dynamisches Objekt handelt: Kopiert die from-Eigenschaft in den von path angegebenen Speicherort, und führt dann einen remove-Vorgang für die from-Eigenschaft aus.

Das folgende Patch-Dokumentbeispiel:

  • Kopiert den Wert der Orders[0].OrderName nach CustomerName.
  • Legt Orders[0].OrderName auf Null fest.
  • Verschiebt Orders[1] vor Orders[0].
[
  {
    "op": "move",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "move",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

Copy-Vorgang (Kopieren)

Dieser Vorgang ist funktionell identisch mit einem move-Vorgang ohne den abschließenden remove-Schritt.

Das folgende Patch-Dokumentbeispiel:

  • Kopiert den Wert der Orders[0].OrderName nach CustomerName.
  • Fügt eine Kopie von Orders[1] vor Orders[0] ein.
[
  {
    "op": "copy",
    "from": "/orders/0/orderName",
    "path": "/customerName"
  },
  {
    "op": "copy",
    "from": "/orders/1",
    "path": "/orders/0"
  }
]

Test-Vorgang (Testen)

Wenn der Wert an dem von path angegebenen Speicherort sich von dem in value bereitgestellten Wert unterscheidet, schlägt die Anforderung fehl. In diesem Fall schlägt die gesamte PATCH-Anforderung fehl, selbst wenn alle anderen Vorgänge im Patch-Dokument ansonsten erfolgreich ausgeführt werden könnten.

Der test-Vorgang wird häufig verwendet, um ein Update zu verhindern, wenn ein Parallelitätskonflikt vorhanden ist.

Das folgende Patch-Dokumentbeispiel hat keine Auswirkungen, wenn der Anfangswert von CustomerName „John“ ist, da der Test fehlschlägt:

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

Abrufen des Codes

Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen)

Um das Beispiel zu testen, führen Sie die App aus, und senden Sie HTTP-Anforderungen mit den folgenden Einstellungen:

  • URL: http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate
  • HTTP-Methode: PATCH
  • Header: Content-Type: application/json-patch+json
  • Textkörper: Kopieren und Einfügen eines der JSON-Patch-Dokumentbeispiele aus dem JSON-Projektordner.

Zusätzliche Ressourcen