Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird erläutert, wie JSON Patch-Anforderungen in einer ASP.NET Core-Web-API behandelt werden.
Die Unterstützung von JSON Patch in ASP.NET Core-Web-API basiert auf der System.Text.Json-Serialisierung und erfordert das Microsoft.AspNetCore.JsonPatch.SystemTextJson
-NuGet-Paket.
Was ist der JSON-Patchstandard?
Der JSON-Patchstandard:
Ist ein Standardformat zum Beschreiben von Änderungen, die auf ein JSON-Dokument angewendet werden sollen.
Ist in RFC 6902 definiert und wird in RESTful-APIs häufig verwendet, um partielle Aktualisierungen an JSON-Ressourcen durchzuführen.
Beschreibt eine Abfolge von Vorgängen, die ein JSON-Dokument ändern, z. B.:
add
remove
replace
move
copy
test
In Web-Apps wird JSON Patch häufig in einem PATCH-Vorgang verwendet, um partielle Aktualisierungen einer Ressource auszuführen. Anstatt die gesamte Ressource für ein Update zu senden, können Clients ein JSON-Patchdokument senden, das nur die Änderungen enthält. Reparieren reduziert die Ladungsgröße und verbessert die Effizienz.
Eine Übersicht über den JSON-Patchstandard finden Sie unter jsonpatch.com.
JSON-Patchunterstützung in ASP.NET Core-Web-API
JSON Patch-Support in der ASP.NET Core-Web-API basiert auf „System.Text.Json“-Serialisierung, beginnend mit .NET 10, und implementiert „Microsoft.AspNetCore.JsonPatch“ basierend auf „System.Text.Json“-Serialisierung. Mithilfe dieser Funktion
- Erfordert das
Microsoft.AspNetCore.JsonPatch.SystemTextJson
NuGet-Paket. - Richtet sich an modernen .NET-Methoden durch Nutzung der System.Text.Json Bibliothek, die für .NET optimiert ist.
- Bietet eine verbesserte Leistung und verringerte Speicherauslastung im Vergleich zur legacybasierten
Newtonsoft.Json
Implementierung. Weitere Informationen zur legacybasiertenNewtonsoft.Json
Implementierung finden Sie in der .NET 9-Version dieses Artikels.
Hinweis
Die Implementierung von Microsoft.AspNetCore.JsonPatch basierend auf der Serialisierung von System.Text.Json ist kein direkter Ersatz für die Vorgänger-Implementierung, die auf Newtonsoft.Json
basiert. Es unterstützt keine dynamischen Typen, z. B. ExpandoObject.
Von Bedeutung
Der JSON Patch-Standard hat inhärente Sicherheitsrisiken. Da diese Risiken dem JSON Patch-Standard inhärent sind, versucht die ASP.NET Core-Implementierung nicht, inhärente Sicherheitsrisiken zu mindern. Es liegt in der Verantwortung des Entwicklers, sicherzustellen, dass das JSON-Patchdokument sicher auf das Zielobjekt angewendet werden kann. Weitere Informationen finden Sie im Abschnitt "Minderung von Sicherheitsrisiken" .
Aktivieren der JSON-Patchunterstützung mit System.Text.Json
Um die JSON-Patchunterstützung mit System.Text.Jsonzu aktivieren, installieren Sie das Microsoft.AspNetCore.JsonPatch.SystemTextJson
NuGet-Paket.
dotnet add package Microsoft.AspNetCore.JsonPatch.SystemTextJson --prerelease
Dieses Paket stellt eine JsonPatchDocument<TModel> Klasse bereit, um ein JSON Patch-Dokument für Objekte vom Typ T
darzustellen und benutzerdefinierte Logik zum Serialisieren und Deserialisieren von JSON Patch-Dokumenten mithilfe von System.Text.Json bereitzustellen. Die Schlüsselmethode der JsonPatchDocument<TModel> Klasse ist ApplyTo(Object), die die Patchvorgänge auf ein Zielobjekt vom Typ T
anwendet.
Aktionsmethodencode, der JSON-Patch anwendet
Eine Aktionsmethode für JSON Patch in einem API-Controller:
- Ist versehen mit dem HttpPatchAttribute-Attribut.
- Akzeptiert eine JsonPatchDocument<TModel>-Klasse, in der Regel mit FromBodyAttribute.
- Ruft ApplyTo(Object) für das Patch-Dokument auf, um die Änderungen anzuwenden.
Beispiel-Controlleraktionsmethode:
[HttpPatch("{id}", Name = "UpdateCustomer")]
public IActionResult Update(AppDb db, string id, [FromBody] JsonPatchDocument<Customer> patchDoc)
{
// Retrieve the customer by ID
var customer = db.Customers.FirstOrDefault(c => c.Id == id);
// Return 404 Not Found if customer doesn't exist
if (customer == null)
{
return NotFound();
}
patchDoc.ApplyTo(customer, jsonPatchError =>
{
var key = jsonPatchError.AffectedObject.GetType().Name;
ModelState.AddModelError(key, jsonPatchError.ErrorMessage);
}
);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return new ObjectResult(customer);
}
Dieser Code aus der Beispiel-App funktioniert mit den folgenden Customer
und Order
Modellen:
namespace App.Models;
public class Customer
{
public string Id { get; set; }
public string? Name { get; set; }
public string? Email { get; set; }
public string? PhoneNumber { get; set; }
public string? Address { get; set; }
public List<Order>? Orders { get; set; }
public Customer()
{
Id = Guid.NewGuid().ToString();
}
}
namespace App.Models;
public class Order
{
public string Id { get; set; }
public DateTime? OrderDate { get; set; }
public DateTime? ShipDate { get; set; }
public decimal TotalAmount { get; set; }
public Order()
{
Id = Guid.NewGuid().ToString();
}
}
Die wichtigsten Schritte der Beispielaktionsmethode:
- Kunden abrufen:
- Die Methode ruft ein
Customer
Objekt aus der DatenbankAppDb
mithilfe der bereitgestellten ID ab. - Wenn kein
Customer
Objekt gefunden wird, wird eine404 Not Found
Antwort zurückgegeben.
- Die Methode ruft ein
- JSON-Patch anwenden:
- Die ApplyTo(Object) Methode wendet die JSON-Patchvorgänge aus dem patchDoc auf das abgerufene
Customer
Objekt an. - Wenn Während der Patchanwendung Fehler auftreten, z. B. ungültige Vorgänge oder Konflikte, werden sie von einem Fehlerbehandlungsdelegat erfasst. Dieser Delegat fügt dem
ModelState
Fehlermeldungen hinzu, indem er den Typnamen des betroffenen Objekts und die Fehlermeldung verwendet.
- Die ApplyTo(Object) Methode wendet die JSON-Patchvorgänge aus dem patchDoc auf das abgerufene
- ModelState überprüfen:
- Nachdem der Patch angewendet wurde, überprüft die Methode das
ModelState
auf Fehler. - Wenn dies
ModelState
ungültig ist, z. B. aufgrund von Patchfehlern, wird eine400 Bad Request
Antwort mit den Überprüfungsfehlern zurückgegeben.
- Nachdem der Patch angewendet wurde, überprüft die Methode das
- Den aktualisierten Kunden zurückgeben:
- Wenn der Patch erfolgreich angewendet wurde und
ModelState
gültig ist, gibt die Methode das aktualisierteCustomer
Objekt in der Antwort zurück.
- Wenn der Patch erfolgreich angewendet wurde und
Beispielfehlerantwort:
Das folgende Beispiel zeigt den Textkörper einer 400 Bad Request
Antwort für einen JSON-Patchvorgang, wenn der angegebene Pfad ungültig ist:
{
"Customer": [
"The target location specified by path segment 'foobar' was not found."
]
}
Anwenden eines JSON-Patchdokuments auf ein Objekt
Die folgenden Beispiele veranschaulichen die Verwendung der ApplyTo(Object) Methode zum Anwenden eines JSON-Patchdokuments auf ein Objekt.
Beispiel: Anwenden eines Objekts JsonPatchDocument<TModel> auf ein Objekt
Dies wird im folgenden Beispiel veranschaulicht:
- Die
add
,replace
undremove
Vorgänge. - Operationen auf geschachtelten Eigenschaften.
- Hinzufügen eines neuen Elements zu einem Array.
- Verwendung eines Konverters für JSON-String-Enums in einem JSON-Patchdokument.
// Original object
var person = new Person {
FirstName = "John",
LastName = "Doe",
Email = "johndoe@gmail.com",
PhoneNumbers = [new() {Number = "123-456-7890", Type = PhoneNumberType.Mobile}],
Address = new Address
{
Street = "123 Main St",
City = "Anytown",
State = "TX"
}
};
// Raw JSON patch document
string jsonPatch = """
[
{ "op": "replace", "path": "/FirstName", "value": "Jane" },
{ "op": "remove", "path": "/Email"},
{ "op": "add", "path": "/Address/ZipCode", "value": "90210" },
{ "op": "add", "path": "/PhoneNumbers/-", "value": { "Number": "987-654-3210",
"Type": "Work" } }
]
""";
// Deserialize the JSON patch document
var patchDoc = JsonSerializer.Deserialize<JsonPatchDocument<Person>>(jsonPatch);
// Apply the JSON patch document
patchDoc!.ApplyTo(person);
// Output updated object
Console.WriteLine(JsonSerializer.Serialize(person, serializerOptions));
Im vorherigen Beispiel wird die folgende Ausgabe des aktualisierten Objekts angezeigt:
{
"firstName": "Jane",
"lastName": "Doe",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "TX",
"zipCode": "90210"
},
"phoneNumbers": [
{
"number": "123-456-7890",
"type": "Mobile"
},
{
"number": "987-654-3210",
"type": "Work"
}
]
}
Die ApplyTo(Object) Methode folgt in der Regel den Konventionen und Optionen System.Text.Json für die JsonPatchDocument<TModel>Verarbeitung, einschließlich des Verhaltens, das durch die folgenden Optionen gesteuert wird:
- JsonNumberHandling: Gibt an, ob numerische Eigenschaften aus Zeichenfolgen gelesen werden.
- PropertyNameCaseInsensitive: Ob Eigenschaftenname die Groß-/Kleinschreibung beachten.
Wichtige Unterschiede zwischen System.Text.Json und der neuen JsonPatchDocument<TModel> Implementierung:
- Der Laufzeittyp des Zielobjekts bestimmt, welche Eigenschaften ApplyTo(Object) gepatcht werden, nicht der deklarierte Typ.
- System.Text.Json Deserialisierung basiert auf dem deklarierten Typ, um berechtigte Eigenschaften zu identifizieren.
Beispiel: Anwenden eines JsonPatchDocument mit Fehlerbehandlung
Es gibt verschiedene Fehler, die beim Anwenden eines JSON-Patchdokuments auftreten können. Das Zielobjekt kann beispielsweise nicht über die angegebene Eigenschaft verfügen, oder der angegebene Wert ist mit dem Eigenschaftstyp nicht kompatibel.
JSON Patch
unterstützt den test
Vorgang, der überprüft, ob ein angegebener Wert der Zieleigenschaft entspricht. Wenn dies nicht der Fall ist, wird ein Fehler zurückgegeben.
Im folgenden Beispiel wird veranschaulicht, wie diese Fehler ordnungsgemäß behandelt werden.
Von Bedeutung
Das an die ApplyTo(Object) Methode übergebene Objekt wird vor Ort geändert. Der Aufrufer ist für das Verwerfen von Änderungen verantwortlich, wenn ein Vorgang fehlschlägt.
// Original object
var person = new Person {
FirstName = "John",
LastName = "Doe",
Email = "johndoe@gmail.com"
};
// Raw JSON patch document
string jsonPatch = """
[
{ "op": "replace", "path": "/Email", "value": "janedoe@gmail.com"},
{ "op": "test", "path": "/FirstName", "value": "Jane" },
{ "op": "replace", "path": "/LastName", "value": "Smith" }
]
""";
// Deserialize the JSON patch document
var patchDoc = JsonSerializer.Deserialize<JsonPatchDocument<Person>>(jsonPatch);
// Apply the JSON patch document, catching any errors
Dictionary<string, string[]>? errors = null;
patchDoc!.ApplyTo(person, jsonPatchError =>
{
errors ??= new ();
var key = jsonPatchError.AffectedObject.GetType().Name;
if (!errors.ContainsKey(key))
{
errors.Add(key, new string[] { });
}
errors[key] = errors[key].Append(jsonPatchError.ErrorMessage).ToArray();
});
if (errors != null)
{
// Print the errors
foreach (var error in errors)
{
Console.WriteLine($"Error in {error.Key}: {string.Join(", ", error.Value)}");
}
}
// Output updated object
Console.WriteLine(JsonSerializer.Serialize(person, serializerOptions));
Das vorherige Beispiel führt zu folgender Ausgabe:
Error in Person: The current value 'John' at path 'FirstName' is not equal
to the test value 'Jane'.
{
"firstName": "John",
"lastName": "Smith", <<< Modified!
"email": "janedoe@gmail.com", <<< Modified!
"phoneNumbers": []
}
Risikominderung bei der IT-Sicherheit
Bei der Verwendung des Microsoft.AspNetCore.JsonPatch.SystemTextJson
Pakets ist es wichtig, potenzielle Sicherheitsrisiken zu verstehen und zu mindern. In den folgenden Abschnitten werden die identifizierten Sicherheitsrisiken im Zusammenhang mit JSON-Patch beschrieben und empfohlene Gegenmaßnahmen bereitgestellt, um die sichere Verwendung des Pakets sicherzustellen.
Von Bedeutung
Dies ist keine vollständige Liste der Bedrohungen. App-Entwickler müssen ihre eigenen Bedrohungsmodellüberprüfungen durchführen, um eine appspezifische umfassende Liste zu ermitteln und bei Bedarf geeignete Gegenmaßnahmen zu erstellen. Beispielsweise sollten Apps, die Sammlungen Patchvorgängen zur Verfügung stellen, das Potenzial für algorithmische Komplexitätsangriffe berücksichtigen, wenn diese Vorgänge Elemente am Anfang der Sammlung einfügen oder entfernen.
Um Sicherheitsrisiken beim Integrieren von JSON-Patchfunktionen in ihre Apps zu minimieren, sollten Entwickler:
- Führen Sie umfassende Bedrohungsmodelle für ihre eigenen Apps aus.
- Adressieren Sie identifizierte Bedrohungen.
- Folgen Sie den empfohlenen Gegenmaßnahmen in den folgenden Abschnitten.
Denial of Service (DoS) über Speicherverstärkung
- Szenario: Ein böswilliger Client sendet einen
copy
Vorgang, der große Objektdiagramme mehrmals dupliziert, was zu übermäßigem Arbeitsspeicherverbrauch führt. - Wirkung: Potenzielle nicht genügend Arbeitsspeicher-Bedingungen, die Dienstunterbrechungen verursachen.
- Risikominderung:
- Überprüfen Sie eingehende JSON Patch-Dokumente auf Größe und Struktur vor dem Aufrufen ApplyTo(Object).
- Die Überprüfung muss appspezifisch sein, aber eine Beispielüberprüfung kann ähnlich wie folgt aussehen:
public void Validate(JsonPatchDocument<T> patch)
{
// This is just an example. It's up to the developer to make sure that
// this case is handled properly, based on the app needs.
if (patch.Operations.Where(op=>op.OperationType == OperationType.Copy).Count()
> MaxCopyOperationsCount)
{
throw new InvalidOperationException();
}
}
Geschäftslogik-Subversion
- Szenario: Patchvorgänge können Felder mit impliziten Invarianten (z. B. interne Flags, IDs oder berechnete Felder) bearbeiten, um Geschäftseinschränkungen zu verletzen.
- Auswirkung: Datenintegritätsprobleme und unbeabsichtigtes App-Verhalten.
- Risikominderung:
- Verwenden Sie POCOs (einfache alte CLR-Objekte) mit explizit definierten Eigenschaften, die sicher geändert werden können.
- Vermeiden Sie das Verfügbarmachen vertraulicher oder sicherheitskritischer Eigenschaften im Zielobjekt.
- Wenn ein POCO-Objekt nicht verwendet wird, überprüfen Sie das gepatchte Objekt nach dem Anwenden von Vorgängen, um sicherzustellen, dass Geschäftsregeln und Invarianten nicht verletzt werden.
- Verwenden Sie POCOs (einfache alte CLR-Objekte) mit explizit definierten Eigenschaften, die sicher geändert werden können.
Authentifizierung und Autorisierung
- Szenario: Nicht authentifizierte oder nicht autorisierte Clients senden bösartige JSON-Patchanforderungen.
- Auswirkung: Nicht autorisierter Zugriff, um vertrauliche Daten zu ändern oder das App-Verhalten zu stören.
- Risikominderung:
- Schützen Sie Endpunkte, die JSON-Patchanforderungen mit ordnungsgemäßen Authentifizierungs- und Autorisierungsmechanismen akzeptieren.
- Einschränken des Zugriffs auf vertrauenswürdige Clients oder Benutzer mit entsprechenden Berechtigungen.
Abrufen des Codes
Ansicht 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
- Text Kopieren und einfügen Sie eine der JSON-Reparaturdokument-Stichproben 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.
Von Bedeutung
Der JSON Patch-Standard hat inhärente Sicherheitsrisiken. Diese Implementierung versucht nicht, diese inhärenten Sicherheitsrisiken zu mindern. Es liegt in der Verantwortung des Entwicklers, sicherzustellen, dass das JSON-Patchdokument sicher auf das Zielobjekt angewendet werden kann. Weitere Informationen finden Sie im Abschnitt "Minderung von Sicherheitsrisiken" .
Paketinstallation
JSON-Reparatur-Support in der ASP.NET Core-Web-API basiert auf „Newtonsoft.Json
“ und erfordert das „Microsoft.AspNetCore.Mvc.NewtonsoftJson
“-NuGet-Paket.
Um JSON-Reparieren-Support zu aktivieren:
Installieren Sie das
Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet-Paket.Rufen Sie AddNewtonsoftJson auf. Zum 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 Standard-System.Text.Json
-basierten Eingabe/Ausgabe-Formatierer, die zur Formatierung aller JSON-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 Support für JSON-Reparieren bei der Verwendung von System.Text.Json
Der auf System.Text.Json
-basierte Eingabeformatierer unterstützt JSON Patch nicht. Hinzufügen von Support für JSON Patch unter Verwendung von „Newtonsoft.Json
“, 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
JSON-Patch-Anfragen verarbeiten - Die bestehende
System.Text.Json
-basierte Eingabe und die Formatierer verarbeiten alle anderen JSON-Anfragen 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
JSON Patch ist ein Format zur Spezifikation von Aktualisierungen, die 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.
Zum Beispiel repräsentieren die folgenden JSON-Dokumente eine Ressource, ein JSON-Reparaturdokument für die Ressource und das Ergebnis der Anwendung der Reparaturoperationen.
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 oben stehenden JSON-Code 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 das Anwenden eines JSON-Patch-Dokuments auf eine Ressource vorgenommen werden, sind unteilbar. 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/-
.
Vorgänge
Die folgende Tabelle zeigt unterstützt Vorgänge gemäß der JSON Patch-Spezifikation:
Vorgang | Notizen |
---|---|
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-Reparatur 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<TModel>-Klasse, in der Regel mit
[FromBody]
. - Ruft ApplyTo(Object) für das Patch-Dokument auf, um die Änderungen anzuwenden.
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 vonpath
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 dasfrom
-Element an den Speicherort despath
-Elements und führt dann einenremove
-Vorgang für dasfrom
-Element aus. - Wenn
path
auf eine Eigenschaft verweist: Kopiert den Wert derfrom
-Eigenschaft in diepath
-Eigenschaft, und führt dann einenremove
-Vorgang für diefrom
-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 vonpath
angegebenen Speicherort, und führt dann einenremove
-Vorgang für diefrom
-Eigenschaft aus.
Das folgende Patch-Dokumentbeispiel:
- Kopiert den Wert der
Orders[0].OrderName
nachCustomerName
. - Legt
Orders[0].OrderName
auf Null fest. - Verschiebt
Orders[1]
vorOrders[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
nachCustomerName
. - Fügt eine Kopie von
Orders[1]
vorOrders[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
Ansicht 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
- Text Kopieren und einfügen Sie eine der JSON-Reparaturdokument-Stichproben aus dem JSON-Projektordner.
Risikominderung bei der IT-Sicherheit
Bei verwendung des Microsoft.AspNetCore.JsonPatch
Pakets mit der Newtonsoft.Json
-basierten Implementierung ist es wichtig, potenzielle Sicherheitsrisiken zu verstehen und zu mindern. In den folgenden Abschnitten werden die identifizierten Sicherheitsrisiken im Zusammenhang mit JSON-Patch beschrieben und empfohlene Gegenmaßnahmen bereitgestellt, um die sichere Verwendung des Pakets sicherzustellen.
Von Bedeutung
Dies ist keine vollständige Liste der Bedrohungen. App-Entwickler müssen ihre eigenen Bedrohungsmodellüberprüfungen durchführen, um eine appspezifische umfassende Liste zu ermitteln und bei Bedarf geeignete Gegenmaßnahmen zu erstellen. Beispielsweise sollten Apps, die Sammlungen Patchvorgängen zur Verfügung stellen, das Potenzial für algorithmische Komplexitätsangriffe berücksichtigen, wenn diese Vorgänge Elemente am Anfang der Sammlung einfügen oder entfernen.
Wenn Sie umfassende Bedrohungsmodelle für ihre eigenen Apps ausführen und identifizierte Bedrohungen adressieren und dabei die unten empfohlenen Gegenmaßnahmen befolgen, können Verbraucher dieser Pakete JSON-Patchfunktionen in ihre Apps integrieren und gleichzeitig Sicherheitsrisiken minimieren.
Denial of Service (DoS) über Speicherverstärkung
- Szenario: Ein böswilliger Client sendet einen
copy
Vorgang, der große Objektdiagramme mehrmals dupliziert, was zu übermäßigem Arbeitsspeicherverbrauch führt. - Wirkung: Potenzielle nicht genügend Arbeitsspeicher-Bedingungen, die Dienstunterbrechungen verursachen.
- Risikominderung:
- Überprüfen Sie eingehende JSON Patch-Dokumente auf Größe und Struktur vor dem Aufrufen
ApplyTo
. - Die Überprüfung muss appspezifisch sein, aber eine Beispielüberprüfung kann ähnlich wie folgt aussehen:
- Überprüfen Sie eingehende JSON Patch-Dokumente auf Größe und Struktur vor dem Aufrufen
public void Validate(JsonPatchDocument patch)
{
// This is just an example. It's up to the developer to make sure that
// this case is handled properly, based on the app needs.
if (patch.Operations.Where(op => op.OperationType == OperationType.Copy).Count()
> MaxCopyOperationsCount)
{
throw new InvalidOperationException();
}
}
Geschäftslogik-Subversion
- Szenario: Patchvorgänge können Felder mit impliziten Invarianten (z. B. interne Flags, IDs oder berechnete Felder) bearbeiten, um Geschäftseinschränkungen zu verletzen.
- Auswirkung: Datenintegritätsprobleme und unbeabsichtigtes App-Verhalten.
- Risikominderung:
- Verwenden Sie POCO-Objekte mit explizit definierten Eigenschaften, die sicher geändert werden können.
- Vermeiden Sie das Verfügbarmachen vertraulicher oder sicherheitskritischer Eigenschaften im Zielobjekt.
- Wenn kein POCO-Objekt verwendet wird, überprüfen Sie das gepatchte Objekt nach dem Anwenden von Vorgängen, um sicherzustellen, dass Geschäftsregeln und Invarianten nicht verletzt werden.
Authentifizierung und Autorisierung
- Szenario: Nicht authentifizierte oder nicht autorisierte Clients senden bösartige JSON-Patchanforderungen.
- Auswirkung: Nicht autorisierter Zugriff, um vertrauliche Daten zu ändern oder das App-Verhalten zu stören.
- Risikominderung:
- Schützen Sie Endpunkte, die JSON-Patchanforderungen mit ordnungsgemäßen Authentifizierungs- und Autorisierungsmechanismen akzeptieren.
- Einschränken des Zugriffs auf vertrauenswürdige Clients oder Benutzer mit entsprechenden Berechtigungen.
Zusätzliche Ressourcen
In diesem Artikel wird erläutert, wie JSON Patch-Anforderungen in einer ASP.NET Core-Web-API behandelt werden.
Von Bedeutung
Der JSON Patch-Standard hat inhärente Sicherheitsrisiken. Da diese Risiken dem JSON Patch-Standard inhärent sind, versucht diese Implementierung nicht, inhärente Sicherheitsrisiken zu mindern. Es liegt in der Verantwortung des Entwicklers, sicherzustellen, dass das JSON-Patchdokument sicher auf das Zielobjekt angewendet werden kann. Weitere Informationen finden Sie im Abschnitt "Minderung von Sicherheitsrisiken" .
Paketinstallation
Um JSON-Patch-Support in Ihrer App zu aktivieren, folgen Sie diesen Schritten:
Installieren Sie das
Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet-Paket.Aktualisieren Sie die
Startup.ConfigureServices
-Methode des Projekts so, dass diese AddNewtonsoftJson aufruft. Zum Beispiel:services .AddControllersWithViews() .AddNewtonsoftJson();
AddNewtonsoftJson
ist kompatibel mit den MVC-Dienstregistrierungsmethoden:
JSON-Reparatur, Hinzufügen von NewtonsoftJson und System.Text.Json
AddNewtonsoftJson
ersetzt die auf System.Text.Json
basierenden Eingabe/Ausgabe-Formatierer, die zur Formatierung von alle JSON-Inhalte verwendet werden. Um Support für JSON Patch mit „Newtonsoft.Json
“ hinzuzufügen, während die anderen Formatierer unverändert bleiben, aktualisieren Sie die Projekt-Startup.ConfigureServices
-Methode 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
JSON Patch ist ein Format zur Spezifikation von Aktualisierungen, die 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.
Zum Beispiel repräsentieren die folgenden JSON-Dokumente eine Ressource, ein JSON-Reparaturdokument für die Ressource und das Ergebnis der Anwendung der Reparaturoperationen.
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 oben stehenden JSON-Code 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 das Anwenden eines JSON-Patch-Dokuments auf eine Ressource vorgenommen werden, sind unteilbar. 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/-
.
Vorgänge
Die folgende Tabelle zeigt unterstützt Vorgänge gemäß der JSON Patch-Spezifikation:
Vorgang | Notizen |
---|---|
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-Reparatur 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.
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 vonpath
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 dasfrom
-Element an den Speicherort despath
-Elements und führt dann einenremove
-Vorgang für dasfrom
-Element aus. - Wenn
path
auf eine Eigenschaft verweist: Kopiert den Wert derfrom
-Eigenschaft in diepath
-Eigenschaft, und führt dann einenremove
-Vorgang für diefrom
-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 vonpath
angegebenen Speicherort, und führt dann einenremove
-Vorgang für diefrom
-Eigenschaft aus.
Das folgende Patch-Dokumentbeispiel:
- Kopiert den Wert der
Orders[0].OrderName
nachCustomerName
. - Legt
Orders[0].OrderName
auf Null fest. - Verschiebt
Orders[1]
vorOrders[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
nachCustomerName
. - Fügt eine Kopie von
Orders[1]
vorOrders[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
Ansicht 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
- Text Kopieren und einfügen Sie eine der JSON-Reparaturdokument-Stichproben aus dem JSON-Projektordner.