ASP.NET Core web apı 'sinde jsonpatch
, Tom Dykstra ve Kirk larkabağı tarafından
bu makalede, ASP.NET Core web apı 'sinde JSON Patch isteklerinin nasıl işleneceği açıklanır.
Paket yüklemesi
Uygulamanızda JSON yama desteğini etkinleştirmek için aşağıdaki adımları izleyin:
Microsoft.AspNetCore.Mvc.NewtonsoftJsonNuGet paketini yükler.Startup.ConfigureServicesÇağırmak için projenin metodunu güncelleştirin AddNewtonsoftJson . Örnek:services .AddControllersWithViews() .AddNewtonsoftJson();
AddNewtonsoftJson , MVC hizmeti kayıt yöntemleriyle uyumludur:
JSON Patch, AddNewtonsoftJson ve System.Text.Js
AddNewtonsoftJson``System.Text.Json Tüm JSON içeriğini biçimlendirmek için kullanılan tabanlı giriş ve çıkış biçimlerini değiştirir. Kullanarak JSON Patch desteği eklemek için Newtonsoft.Json , diğer biçimleri değişmeden bırakarak, projenin Startup.ConfigureServices yöntemini aşağıdaki gibi güncelleştirin:
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();
}
Yukarıdaki kod, Microsoft.AspNetCore.Mvc.NewtonsoftJson paketi ve aşağıdaki using deyimlerini gerektirir:
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.SerializeObjectBir JsonPatchDocument seri hale getirmek için yöntemini kullanın.
PATCH HTTP istek yöntemi
PUT ve Patch yöntemleri, var olan bir kaynağı güncelleştirmek için kullanılır. Bunlar arasındaki fark, PUT 'ın tüm kaynağı değiştirmesi, ancak düzeltme eki yalnızca değişiklikleri belirttiğinde.
JSON yaması
JSON yaması , bir kaynağa uygulanacak güncelleştirmelerin belirtilmesine yönelik bir biçimdir. JSON yama belgesinde bir dizi işlem vardır. Her işlem belirli bir değişiklik türünü tanımlar. Bu tür değişikliklere örnek olarak bir dizi öğesi ekleme veya bir özellik değeri değiştirme sayılabilir.
Örneğin, aşağıdaki JSON belgeleri bir kaynağı, kaynak için bir JSON yama belgesini ve düzeltme eki işlemlerini uygulamanın sonucunu temsil eder.
Kaynak örneği
{
"customerName": "John",
"orders": [
{
"orderName": "Order0",
"orderType": null
},
{
"orderName": "Order1",
"orderType": null
}
]
}
JSON Patch örneği
[
{
"op": "add",
"path": "/customerName",
"value": "Barry"
},
{
"op": "add",
"path": "/orders/-",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Yukarıdaki JSON kodunda:
opÖzelliği, işlem türünü gösterir.pathÖzelliği güncelleştirilecek öğeyi gösterir.valueÖzelliği yeni değeri sağlar.
Düzeltme ekiyle sonra kaynak
Önceki JSON Patch belgesi uygulandıktan sonra kaynak şu şekildedir:
{
"customerName": "Barry",
"orders": [
{
"orderName": "Order0",
"orderType": null
},
{
"orderName": "Order1",
"orderType": null
},
{
"orderName": "Order2",
"orderType": null
}
]
}
Bir kaynak için bir JSON Patch belgesi uygulanarak yapılan değişiklikler atomik. Listedeki herhangi bir işlem başarısız olursa, listede hiçbir işlem uygulanmaz.
Yol sözdizimi
Bir işlem nesnesinin Path özelliği düzeyler arasında eğik çizgi içeriyor. Örneğin, "/address/zipCode".
Sıfır tabanlı dizinler, dizi öğelerini belirtmek için kullanılır. Dizinin ilk öğesi addresses /addresses/0 . addBir dizinin sonuna kadar, - Dizin numarası yerine bir tire () kullanın: /addresses/- .
Operations
Aşağıdaki tabloda, JSON Patch belirtimindetanımlanan desteklenen işlemler gösterilmektedir:
| İşlem | Notlar |
|---|---|
add |
Bir özellik veya dizi öğesi ekleyin. Var olan özellik için: set değeri. |
remove |
Bir özellik veya dizi öğesi kaldırın. |
replace |
Aynı remove konumdaki ve sonrasında aynı add . |
move |
Kaynaktaki remove add değeri kullanarak kaynağından sonra hedefle aynı. |
copy |
addKaynaktaki değeri kullanarak hedefle aynı olacak şekilde aynı. |
test |
Değer: belirtilmişse başarı durum kodu döndürür path value . |
ASP.NET Core JSON yaması
JSON düzeltme ekinin ASP.NET Core uygulanması Microsoft.AspNetCore.Jsonpatch NuGet paketinde sunulmaktadır.
Eylem yöntemi kodu
Bir API denetleyicisinde, JSON yaması için bir eylem yöntemi:
- , Özniteliğiyle açıklama eklenir
HttpPatch. JsonPatchDocument<T>, Genellikle ile kabul eder[FromBody].ApplyToDeğişiklikleri uygulamak için düzeltme eki belgesindeki çağrılar.
Aşağıda bir örnek verilmiştir:
[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);
}
}
Örnek uygulamadaki Bu kod aşağıdaki modelle birlikte kullanılabilir Customer :
public class Customer
{
public string CustomerName { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public string OrderName { get; set; }
public string OrderType { get; set; }
}
Örnek eylem yöntemi:
- Bir oluşturur
Customer. - Düzeltme ekini uygular.
- Yanıtın gövdesinde sonucu döndürür.
Gerçek bir uygulamada, kod veritabanı gibi bir mağazadan verileri alır ve düzeltme ekini uyguladıktan sonra veritabanını güncelleştirir.
Model durumu
Önceki eylem yöntemi örneği, ApplyTo parametrelerinden biri olarak model durumunu alan aşırı yüklemesini çağırır. Bu seçenekle, yanıtlardan hata iletileri alabilirsiniz. Aşağıdaki örnekte bir işlem için 400 Hatalı Istek yanıtının gövdesi gösterilmektedir test :
{
"Customer": [
"The current value 'John' at path 'customerName' is not equal to the test value 'Nancy'."
]
}
Dinamik nesneler
Aşağıdaki eylem yöntemi örneği, dinamik bir nesneye nasıl düzeltme eki uygulanacağını gösterir:
[HttpPatch]
public IActionResult JsonPatchForDynamic([FromBody]JsonPatchDocument patch)
{
dynamic obj = new ExpandoObject();
patch.ApplyTo(obj);
return Ok(obj);
}
Ekleme işlemi
pathBir dizi öğesine işaret ediyorsa: tarafından belirtiden önce yeni bir öğe eklerpath.pathBir özelliğe işaret ediyorsa: özellik değerini ayarlar.pathVarolmayan bir konuma işaret ediyorsa:- Yama yapılacak kaynak dinamik bir nesnedir: bir özellik ekler.
- Yama yapılacak kaynak statik bir nesnese: istek başarısız olur.
Aşağıdaki örnek düzeltme eki belgesi değerini ayarlar CustomerName ve Order dizinin sonuna bir nesnesi ekler Orders .
[
{
"op": "add",
"path": "/customerName",
"value": "Barry"
},
{
"op": "add",
"path": "/orders/-",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Kaldırma işlemi
pathBir dizi öğesine işaret ediyorsa: öğesini kaldırır.pathBir özelliğe işaret ediyorsa:- Yayama kaynağı dinamik bir nesne ise: özelliğini kaldırır.
- Yama yapılacak kaynak statik bir nesnese:
- Özellik null atanabilir ise: null olarak ayarlar.
- Özellik null atanamaz ise, olarak ayarlar
default<T>.
Aşağıdaki örnek düzeltme eki belgesi CustomerName null ve siler olarak ayarlanır Orders[0] :
[
{
"op": "remove",
"path": "/customerName"
},
{
"op": "remove",
"path": "/orders/0"
}
]
Değiştirme işlemi
Bu işlem, bir remove sonrasında bir ile aynıdır add .
Aşağıdaki örnek düzeltme eki belgesi değerini ayarlar CustomerName ve Orders[0] Yeni bir Order nesneyle değiştirir:
[
{
"op": "replace",
"path": "/customerName",
"value": "Barry"
},
{
"op": "replace",
"path": "/orders/0",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Taşıma işlemi
pathBir dizi öğesinin işaret ediyorsa: öğesini öğesininfromkonumuna kopyalarpath, sonraremoveöğesi üzerinde bir işlem çalıştırırfrom.pathBir özelliğe işaret ediyorsa: özelliğin değerini özelliğine kopyalarfrompathve sonraremoveözelliği üzerinde bir işlem çalıştırırfrom.pathVarolmayan bir özelliğe işaret ediyorsa:- Yama yapılacak kaynak statik bir nesnese: istek başarısız olur.
- Yaması gereken kaynak dinamik bir nesnedir:
fromözelliği tarafından belirtilen konuma kopyalarpath, sonraremoveözellik üzerinde bir işlem çalıştırırfrom.
Aşağıdaki örnek düzeltme eki belgesi:
- Değerini
Orders[0].OrderNameolarak kopyalarCustomerName. Orders[0].OrderNameNull olarak ayarlar.Orders[1]Öncesine giderOrders[0].
[
{
"op": "move",
"from": "/orders/0/orderName",
"path": "/customerName"
},
{
"op": "move",
"from": "/orders/1",
"path": "/orders/0"
}
]
Kopyalama işlemi
Bu işlem, son adım olmadan bir move işlemle işlevsel olarak remove aynıdır.
Aşağıdaki örnek düzeltme eki belgesi:
- değerini değerine
Orders[0].OrderNameCustomerNamekopyalar. - önce bir kopyasını
Orders[1]Orders[0]ekler.
[
{
"op": "copy",
"from": "/orders/0/orderName",
"path": "/customerName"
},
{
"op": "copy",
"from": "/orders/1",
"path": "/orders/0"
}
]
Test işlemi
tarafından belirtilen konumdaki değer içinde sağlanan değerden farklı path ise istek başarısız value olur. Bu durumda, yama belgesinde diğer tüm işlemler başarılı olsa bile PATCH isteğinin tamamı başarısız olur.
İşlem test genellikle eşzamanlılık çakışması olduğunda bir güncelleştirmeyi önlemek için kullanılır.
Aşağıdaki örnek düzeltme eki belgesinin ilk değeri "John" ise hiçbir etkisi CustomerName yoktur çünkü test başarısız olur:
[
{
"op": "test",
"path": "/customerName",
"value": "Nancy"
},
{
"op": "add",
"path": "/customerName",
"value": "Barry"
}
]
Kodu alma
Örnek kodu görüntüleme veya indirme. (İndirme).
Örneği test etmek için uygulamayı çalıştırın ve aşağıdaki ayarlarla HTTP istekleri gönderin:
- Url:
http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate - HTTP yöntemi:
PATCH - Üstbilgi:
Content-Type: application/json-patch+json - Gövde: JSON proje klasöründeki JSON düzeltme eki belge örneklerinden birini kopyalayıp yapıştırın.
Ek kaynaklar
- IETF RFC 5789 PATCH yöntemi belirtimi
- IETF RFC 6902 JSON Düzeltme Eki belirtimi
- IETF RFC 6901 JSON Düzeltme Eki yol biçimi özellikleri
- JSON Patch belgeleri. JSON Patch belgeleri oluşturmak için kaynakların bağlantılarını içerir.
- ASP.NET Core JSON Düzeltme Eki kaynak kodu
Bu makalede, bir web API'sinde JSON Patch isteklerini ASP.NET Core açıklanmıştır.
PATCH HTTP isteği yöntemi
PUT ve PATCH yöntemleri, mevcut bir kaynağı güncelleştirmek için kullanılır. Aralarındaki fark PUT'ın kaynağın tamamını değiştirmesi, PATCH ise yalnızca değişiklikleri belirtir.
JSON Düzeltme Eki
JSON Patch, bir kaynağa uygulanacak güncelleştirmeleri belirtme biçimidir. JSON Patch belgesi bir dizi işlem içerir. Her işlem, dizi öğesi ekleme veya bir özellik değerini değiştirme gibi belirli bir değişiklik türünü tanımlar.
Örneğin, aşağıdaki JSON belgeleri bir kaynağı, kaynak için bir JSON düzeltme eki belgesini ve düzeltme eki işlemlerinin uygulanmasına yönelik sonucu temsil ediyor.
Kaynak örneği
{
"customerName": "John",
"orders": [
{
"orderName": "Order0",
"orderType": null
},
{
"orderName": "Order1",
"orderType": null
}
]
}
JSON düzeltme eki örneği
[
{
"op": "add",
"path": "/customerName",
"value": "Barry"
},
{
"op": "add",
"path": "/orders/-",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Yukarıdaki JSON kodunda:
opözelliği, işlem türünü gösterir.- özelliği,
pathgüncelleştirilen öğeyi gösterir. - özelliği
valueyeni değeri sağlar.
Düzeltme eki sonrası kaynak
Önceki JSON Düzeltme Eki belgesini uygulamadan sonraki kaynak şu şekildedir:
{
"customerName": "Barry",
"orders": [
{
"orderName": "Order0",
"orderType": null
},
{
"orderName": "Order1",
"orderType": null
},
{
"orderName": "Order2",
"orderType": null
}
]
}
Bir kaynağa JSON Düzeltme Eki belgesi uygulanarak yapılan değişiklikler atomiktir: listede herhangi bir işlem başarısız olursa, listede hiçbir işlem uygulanmaz.
Yol söz dizimi
Bir işlem nesnesinin path özelliği, düzeyler arasında eğik çizgi içerir. Örneğin, "/address/zipCode".
Dizi öğelerini belirtmek için sıfır tabanlı dizinler kullanılır. Dizinin ilk öğesi addresses /addresses/0 şudur: . Bir add dizinin sonuna bir dizin numarası yerine kısa çizgi (-) kullanın: /addresses/- .
Operations
Aşağıdaki tabloda, JSONDüzeltme Eki belirtimsinde tanımlanan desteklenen işlemler yer alır:
| İşlem | Notlar |
|---|---|
add |
Özellik veya dizi öğesi ekleyin. Mevcut özellik için: değeri ayarlayın. |
remove |
Bir özelliği veya dizi öğesini kaldırın. |
replace |
Takip remove ettiği add konumla aynı. |
move |
Kaynaktan gelen remove değeri kullanarak kaynaktan sonra hedefe kadar add olanlarla aynı. |
copy |
Kaynaktan değer add kullanan hedefle aynı. |
test |
değeri = sağlandı ise başarı path durumu kodunu geri value dönme. |
ASP.NET Core'de JsonPatch
JSON ASP.NET Core uygulama, Microsoft.AspNetCore.JsonPatch NuGet sağlanır. Paket, meta Microsoft.AspnetCore.App dahil edilir.
Eylem yöntemi kodu
API denetleyicisinde JSON Patch için bir eylem yöntemi:
- özniteliğiyle açıklama
HttpPatchek açıklamalıdır. - , genellikle
JsonPatchDocument<T>ile kabul[FromBody]eder. - Değişiklikleri
ApplyTouygulamak için yama belgesine çağrılar.
Aşağıda bir örnek verilmiştir:
[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);
}
}
Örnek uygulamanın bu kodu aşağıdaki modelle Customer çalışır.
public class Customer
{
public string CustomerName { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public string OrderName { get; set; }
public string OrderType { get; set; }
}
Örnek eylem yöntemi:
- bir
Customeryapısındadır. - Düzeltme ekini uygular.
- Yanıtın gövdesinde sonucu döndürür.
Gerçek bir uygulamada kod, verileri veritabanı gibi bir depodan alır ve düzeltme ekini uygulamaya başladıktan sonra veritabanını güncelleştirer.
Model durumu
Yukarıdaki eylem yöntemi örneği, parametrelerinden biri ApplyTo olarak model durumunu alan bir aşırı yüklemesini çağırıyor. Bu seçenekle, yanıtlarda hata iletileri alabilirsiniz. Aşağıdaki örnek, bir işlem için 400 Hatalı İstek yanıtının gövdesini test gösterir:
{
"Customer": [
"The current value 'John' at path 'customerName' is not equal to the test value 'Nancy'."
]
}
Dinamik nesneler
Aşağıdaki eylem yöntemi örneğinde, dinamik bir nesneye düzeltme eki uygulama işlemi gösterir.
[HttpPatch]
public IActionResult JsonPatchForDynamic([FromBody]JsonPatchDocument patch)
{
dynamic obj = new ExpandoObject();
patch.ApplyTo(obj);
return Ok(obj);
}
Ekleme işlemi
- Bir
pathdizi öğesini gösterirse: tarafından belirtilen öğeden önce yeni öğepathekler. - Bir
pathözelliğin değerinin yer alıyorsa: özellik değerini ayarlar. - Var
patholan bir konumun yeri ise:- Düzeltme eki uygulama kaynağı dinamik bir nesne ise: bir özellik ekler.
- Düzeltme eki uygulama kaynağı statik bir nesne ise istek başarısız olur.
Aşağıdaki örnek düzeltme eki belgesi değerini ayarlar CustomerName ve Order dizisinin sonuna bir nesnesi Orders ekler.
[
{
"op": "add",
"path": "/customerName",
"value": "Barry"
},
{
"op": "add",
"path": "/orders/-",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Kaldırma işlemi
- Bir
pathdizi öğesini işaret ediyorsa: öğesini kaldırır. - Bir
pathözelliğin noktası ise:- Düzeltme eki uygulama kaynağı dinamik bir nesne ise: özelliğini kaldırır.
- Düzeltme eki uygulama kaynağı statik bir nesne ise:
- Özellik null değere sahipse: null olarak ayarlar.
- Özelliği null değere sahip olmayan bir özellik olarak
default<T>ayarlar.
Aşağıdaki örnek düzeltme eki belgesi CustomerName null olarak ayarlanır ve Orders[0] siler.
[
{
"op": "remove",
"path": "/customerName"
},
{
"op": "remove",
"path": "/orders/0"
}
]
Değiştirme işlemi
Bu işlem işlevsel olarak ile ve ardından remove bir ile add aynıdır.
Aşağıdaki örnek düzeltme eki belgesi değerini ayarlar CustomerName ve değerini yeni bir Orders[0] nesneyle Order değiştirir.
[
{
"op": "replace",
"path": "/customerName",
"value": "Barry"
},
{
"op": "replace",
"path": "/orders/0",
"value": {
"orderName": "Order2",
"orderType": null
}
}
]
Taşıma işlemi
pathBir dizi öğesinin işaret ediyorsa: öğesini öğesininfromkonumuna kopyalarpath, sonraremoveöğesi üzerinde bir işlem çalıştırırfrom.pathBir özelliğe işaret ediyorsa: özelliğin değerini özelliğine kopyalarfrompathve sonraremoveözelliği üzerinde bir işlem çalıştırırfrom.pathVarolmayan bir özelliğe işaret ediyorsa:- Yama yapılacak kaynak statik bir nesnese: istek başarısız olur.
- Yaması gereken kaynak dinamik bir nesnedir:
fromözelliği tarafından belirtilen konuma kopyalarpath, sonraremoveözellik üzerinde bir işlem çalıştırırfrom.
Aşağıdaki örnek düzeltme eki belgesi:
- Değerini
Orders[0].OrderNameolarak kopyalarCustomerName. Orders[0].OrderNameNull olarak ayarlar.Orders[1]Öncesine giderOrders[0].
[
{
"op": "move",
"from": "/orders/0/orderName",
"path": "/customerName"
},
{
"op": "move",
"from": "/orders/1",
"path": "/orders/0"
}
]
Kopyalama işlemi
Bu işlem, move son adım olmadan işlem ile aynı şekilde aynıdır remove .
Aşağıdaki örnek düzeltme eki belgesi:
- Değerini
Orders[0].OrderNameolarak kopyalarCustomerName. - Daha önce bir kopyası
Orders[1]eklerOrders[0].
[
{
"op": "copy",
"from": "/orders/0/orderName",
"path": "/customerName"
},
{
"op": "copy",
"from": "/orders/1",
"path": "/orders/0"
}
]
Test işlemi
Tarafından belirtilen konumdaki değer path içinde belirtilen değerden farklıysa value , istek başarısız olur. Bu durumda, yama belgesindeki diğer tüm işlemler başka bir şekilde başarılı olsa bile, tüm yama isteği başarısız olur.
İşlem, bir test eşzamanlılık çakışması olduğunda bir güncelleştirmeyi engellemek için yaygın olarak kullanılır.
Aşağıdaki örnek düzeltme eki belgesinin ilk değeri CustomerName "John" ise, test başarısız olursa hiçbir etkisi yoktur:
[
{
"op": "test",
"path": "/customerName",
"value": "Nancy"
},
{
"op": "add",
"path": "/customerName",
"value": "Barry"
}
]
Kodu alma
Örnek kodu görüntüleyin veya indirin. (İndirme).
Örneği test etmek için, uygulamayı çalıştırın ve aşağıdaki ayarlarla HTTP istekleri gönderin:
- 'DEKI
http://localhost:{port}/jsonpatch/jsonpatchwithmodelstate - HTTP yöntemi:
PATCH - Üst bilgi
Content-Type: application/json-patch+json - Gövde: JSON proje klasöründen JSON Patch belgesi örneklerinden birini kopyalayıp yapıştırın.
Ek kaynaklar
- IETF RFC 5789 PATCH yöntemi belirtimi
- IETF RFC 6902 JSON Patch belirtimi
- IETF RFC 6901 JSON Patch yolu biçim belirtimi
- JSON yama belgeleri. JSON yama belgeleri oluşturmak için kaynakların bağlantılarını içerir.
- ASP.NET Core JSON Patch kaynak kodu