C# 对JSON对象的一部分进行反序列化,并将其序列化回来,而其余属性保持不变

C# 对JSON对象的一部分进行反序列化,并将其序列化回来,而其余属性保持不变,c#,json.net,C#,Json.net,我有一些JSON,我想反序列化到C#类的实例中。但是,该类没有与原始JSON匹配的所有字段/属性。我希望能够修改类中的属性值,然后将其序列化回JSON,而原始JSON中的其余字段和属性仍然保持不变 例如,假设我有以下JSON: { "name": "david", "age": 100, "sex": "M", "address": "far far away" } 我想把它反序列化到这个类中: class MyClass { public str

我有一些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.Net的“扩展数据”功能来处理这一点

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

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

    [JsonExtensionData]
    private Dictionary<string, object> otherStuff { get; set; }
}

好的,在发帖后,我去吃午饭,回来后我找到了解决办法。我没有使用JSON.net的“扩展数据”,而是发现它们有一个“合并”函数

在我看来,这是更清洁,并决定采用这种方法

下面是我写的一个例子

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 
公共类单元格
{
公共字符串文本{get;set;}
公共int ID{get;set;}
公共单元格样式{get;set;}
}
公务舱
{
公共字符串BgColor{get;set;}
公共字符串TextColor{get;set;}
}
字符串json=@”{
“文本”:“我的手机”,
身份证号码:20,
“TsID”:100,
“风格”:{
“BgColor”:“Red”,
“文本颜色”:“黑色”,
“说明”:“帮助我的手机”,
}
}";
var orgCell=JsonConvert.DeserializeObject(json);
orgCell.Style.TextColor=“白色”;
orgCell.Style.BgColor=“蓝色”;
var obj=JsonConvert.SerializeObject(orgCell);
JObject o1=JObject.Parse(json);
JObject o2=JObject.Parse(obj);
o1.合并(o2,新JsonMergeSettings
{
//将数组值合并在一起以避免重复
MergeArrayHandling=MergeArrayHandling.Union
});
o1.ToString();//给我指定的字符串

这不完全是您想要的,但这至少是一个解决方案,为什么不将属性添加到类中?@MikkoViitala他可能不知道其他属性是什么,或者它们的名称和编号可能是可变的。@BrianRogers这是对的。实际上JSON非常庞大,只想修改强类型环境中的一些字段,而不必定义所有字段。我确实想出了一个解决办法,我会把它贴在这里,不清楚为什么你会考虑这个清洁工。除了更加复杂之外,从性能的角度来看,您还需要进行两次额外的解析和一次合并。实际上,我还不确定要使用哪种方法。我有点担心,因为JSON本身有多个嵌套层,而且还没有完全测试wyas。但至少我现在有办法解决这个问题
orig name: david
orig age: 100

{
  "name": "john",
  "age": 200,
  "sex": "M",
  "address": "far far away"
}
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