反序列化部分 JSON 对象,并在其余属性不变的情况下将其序列化回去

本文关键字:情况下 序列化 属性 对象 JSON 余属性 反序列化部 | 更新日期: 2023-09-27 18:30:23

我有一些JSON,我想将其反序列化为C#类的实例。 但是,该类没有与原始 JSON 匹配的所有字段/属性。我希望能够修改类中的属性值,然后将其序列化回 JSON,原始 JSON 中的剩余字段和属性仍然完好无损。

例如,假设我有以下 JSON:

{
    "name": "david",
    "age": 100,
    "sex": "M",
    "address": "far far away"
}

我想将其反序列化为此类:

class MyClass 
{  
    public string name { get; set; }  
    public int age { get; set; }  
}

反序列化后,我设置以下内容:

myClass.name = "John";
myClass.age = 200;

现在,我想将其序列化回 JSON 并得到以下结果:

{
    "name": "John",
    "age": 200,
    "sex": "M",
    "address": "far far away"
}

有没有办法使用 Json.Net 来做到这一点?

反序列化部分 JSON 对象,并在其余属性不变的情况下将其序列化回去

您可以使用 Json.Net 的"扩展数据"功能来处理此问题。

向类添加新的 Dictionary<string, object> 属性,并使用 [JsonExtensionData] 属性对其进行标记。 (如果不想影响类的公共接口,可以将其设置为私有属性。 在反序列化时,此字典将填充与类的任何其他公共属性不匹配的任何数据。 在序列化时,字典中的数据将作为对象的属性写回 JSON。

class MyClass
{
    public string name { get; set; }
    public int age { get; set; }
    [JsonExtensionData]
    private Dictionary<string, object> otherStuff { get; set; }
}

这是一个演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {  
            ""name"": ""david"",
            ""age"": 100,
            ""sex"": ""M"",
            ""address"": ""far far away""
        }";
        MyClass obj = JsonConvert.DeserializeObject<MyClass>(json);
        Console.WriteLine("orig name: " + obj.name);
        Console.WriteLine("orig age: " + obj.age);
        Console.WriteLine();
        obj.name = "john";
        obj.age = 200;
        json = JsonConvert.SerializeObject(obj, Formatting.Indented);
        Console.WriteLine(json);
    }
}

输出:

orig name: david
orig age: 100
{
  "name": "john",
  "age": 200,
  "sex": "M",
  "address": "far far away"
}

好的,所以在发布问题后,去吃午饭,回来了,我找到了解决方案。我没有使用JSON.net的"扩展数据",而是发现它们具有"合并"功能http://james.newtonking.com/archive/2014/08/04/json-net-6-0-release-4-json-merge-dependency-injection

IMO 我认为这更干净,并决定采用这种方法。

下面是我正在写的一个示例

public class Cell
{
  public string Text { get; set; }
  public int ID { get; set; }
  public CellStyle Style { get; set; }
}
public class CellStyle
{
  public string BgColor { get; set; }
  public string TextColor { get; set; }
}
string json = @"{
  'Text': 'My Cell',
  'ID': 20,
  'TsID': 100,
  'Style':  {
              'BgColor' : 'Red',
              'TextColor' : 'Black',
              'Caption' : 'Help My Cell',
            }
}";
var orgCell = JsonConvert.DeserializeObject<Cell>(json);
orgCell.Style.TextColor = "White";
orgCell.Style.BgColor = "Blue";
var obj = JsonConvert.SerializeObject(orgCell);
JObject o1 = JObject.Parse(json);
JObject o2 = JObject.Parse(obj);
o1.Merge(o2, new JsonMergeSettings
{
  // union array values together to avoid duplicates
  MergeArrayHandling = MergeArrayHandling.Union
});
o1.ToString(); // gives me the intended string