gpt4 book ai didi

c# - 如何通过比较两个 c# 对象来创建 JsonPatchDocument?

转载 作者:可可西里 更新时间:2023-11-01 03:10:43 35 4
gpt4 key购买 nike

鉴于我有两个相同类型的 c# 对象,我想比较它们以创建一个 JsonPatchDocument。

我有一个这样定义的 StyleDetail 类:

public class StyleDetail
{
public string Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public decimal OriginalPrice { get; set; }
public decimal Price { get; set; }
public string Notes { get; set; }
public string ImageUrl { get; set; }
public bool Wishlist { get; set; }
public List<string> Attributes { get; set; }
public ColourList Colours { get; set; }
public SizeList Sizes { get; set; }
public ResultPage<Style> Related { get; set; }
public ResultPage<Style> Similar { get; set; }
public List<Promotion> Promotions { get; set; }
public int StoreStock { get; set; }
public StyleDetail()
{
Attributes = new List<string>();
Colours = new ColourList();
Sizes = new SizeList();
Promotions = new List<Promotion>();
}
}

如果我有两个 StyleDetail 对象

StyleDetail styleNew = db.GetStyle(123);
StyleDetail styleOld = db.GetStyle(456);

我现在想创建一个 JsonPatchDocument,这样我就可以将差异发送到我的 REST API...该怎么做??

JsonPatchDocument patch = new JsonPatchDocument();
// Now I want to populate patch with the differences between styleNew and styleOld - how?

在 javascript 中,有一个库可以做到这一点 https://www.npmjs.com/package/rfc6902

Calculate diff between two objects:

rfc6902.createPatch({first: 'Chris'}, {first: 'Chris', last: 'Brown'});

[ { op: 'add', path: '/last', value: 'Brown' } ]

但我正在寻找一个 c# 实现

最佳答案

让我们滥用您的类可序列化为 JSON 的事实!这是补丁创建者的第一次尝试,它不关心您的实际对象,只关心该对象的 JSON 表示。

public static JsonPatchDocument CreatePatch(object originalObject, object modifiedObject)
{
var original = JObject.FromObject(originalObject);
var modified = JObject.FromObject(modifiedObject);

var patch = new JsonPatchDocument();
FillPatchForObject(original, modified, patch, "/");

return patch;
}

static void FillPatchForObject(JObject orig, JObject mod, JsonPatchDocument patch, string path)
{
var origNames = orig.Properties().Select(x => x.Name).ToArray();
var modNames = mod.Properties().Select(x => x.Name).ToArray();

// Names removed in modified
foreach (var k in origNames.Except(modNames))
{
var prop = orig.Property(k);
patch.Remove(path + prop.Name);
}

// Names added in modified
foreach (var k in modNames.Except(origNames))
{
var prop = mod.Property(k);
patch.Add(path + prop.Name, prop.Value);
}

// Present in both
foreach (var k in origNames.Intersect(modNames))
{
var origProp = orig.Property(k);
var modProp = mod.Property(k);

if (origProp.Value.Type != modProp.Value.Type)
{
patch.Replace(path + modProp.Name, modProp.Value);
}
else if (!string.Equals(
origProp.Value.ToString(Newtonsoft.Json.Formatting.None),
modProp.Value.ToString(Newtonsoft.Json.Formatting.None)))
{
if (origProp.Value.Type == JTokenType.Object)
{
// Recurse into objects
FillPatchForObject(origProp.Value as JObject, modProp.Value as JObject, patch, path + modProp.Name +"/");
}
else
{
// Replace values directly
patch.Replace(path + modProp.Name, modProp.Value);
}
}
}
}

用法:

var patch = CreatePatch(
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "1", Removed = "1" },
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "2", Added = new { x = "1" } });

// Result of JsonConvert.SerializeObject(patch)
[
{
"path": "/Removed",
"op": "remove"
},
{
"value": {
"x": "1"
},
"path": "/Added",
"op": "add"
},
{
"value": "2",
"path": "/Changed",
"op": "replace"
}
]

关于c# - 如何通过比较两个 c# 对象来创建 JsonPatchDocument?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43692053/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com