Newtonsoft Json Serialize/Deserialize 嵌套 属性
Newtonsoft Json Serialize/Deserialize nested property
我有以下class结构
public class MainClass
{
public string MyStringValue {get;set;}
public SecondClass MyClassValue {get;set;}
}
public class SecondClass
{
public string Value {get;set;}
}
我设置了以下值:
SecondClass secondClass = new SecondClass
{
Value = "Test"
}
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
}
当我序列化 class "mainClass" 时,我得到以下 Json (这对我来说绝对清楚):
{
"MyStringValue":"String Value",
"MyClassValue":
{
"Value":"Test"
}
}
有些情况下我想改为序列化为以下内容:
{
"MyStringValue":"String Value",
"MyClassValue": "Test"
}
子class的字段名总是"Value",这怎么办?
(而且我还需要对相同的结构进行反序列化)
上面的json和后面的不一样。 Main class 不能在没有转换的情况下序列化为 {"MyStringValue":"String Value","MyClassValue": "Test"}
。
var resultObjet = new {
MyStringValue = mainClass.MyStringValue,
MyClassValue = mainClass.SecondClass.MyClassValue
}
然后就可以序列化了
为此,您需要一个新的 class 进行反序列化。但是对于序列化,您可以即时创建一个匿名类型,如下所示:
void Main()
{
// import Newtonsoft.JsonConvert
SecondClass secondClass = new SecondClass
{
Value = "Test"
};
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
};
// The JSON as you expect
var origJson = JsonConvert.SerializeObject(mainClass);
Console.WriteLine(origJson);
// The JSON Deserialized and the second class value outputted
Console.WriteLine(JsonConvert.DeserializeObject<MainClass>(origJson).MyClassValue.Value);
// The modified JSON as you wanted it
var modJson = JsonConvert.SerializeObject(new { mainClass.MyStringValue, MyClassValue = mainClass.MyClassValue.Value });
Console.WriteLine(modJson);
// The modified JSON deserialized
var deserialized = JsonConvert.DeserializeObject<ModMainClass>(modJson);
Console.WriteLine(deserialized.MyStringValue);
}
public class ModMainClass
{
public string MyStringValue { get; set; }
public string MyClassValue { get; set; }
}
public class MainClass
{
public string MyStringValue {get;set;}
public SecondClass MyClassValue {get;set;}
}
public class SecondClass
{
public string Value { get; set; }
}
你有两个选择,一个是@Simonare提到的
或将 class MainClass
的结构更改为
public class MainClass<T>
{
public string MyStringValue { get; set; }
public T MyClassValue { get; set; }
}
public class SecondClass
{
public string Value { get; set; }
}
现在您可以简单地选择要使用的内容作为 MyClassValue
var c = new MainClass<string>();
或
var c = new MainClass<SecondClass>();
实现此目的的一种方法是使用 Custom JsonConverter with the JsonConverterAttribute。例如,您可以为 class:
创建自定义转换器
public class SecondClassConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SecondClass);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
try
{
if (reader.TokenType == JsonToken.String)
{
return new SecondClass
{
Value = reader.Value.ToString()
};
}
}
catch (Exception ex)
{
throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.", ex);
}
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing {nameof(SecondClass)}.");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
var secondClass = (SecondClass)value;
writer.WriteValue(secondClass.Value);
}
}
然后您将 JsonConverterAttribute
与该转换器一起使用:
public class MainClass
{
public string MyStringValue { get; set; }
[JsonConverter(typeof(SecondClassConverter))]
public SecondClass MyClassValue { get; set; }
}
public class SecondClass
{
public string Value { get; set; }
}
这将允许 MainClass
的所有序列化使用 SecondClassConverter
的 WriteJson
方法:
static void Main(string[] args)
{
SecondClass secondClass = new SecondClass
{
Value = "Test"
};
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
};
var json = JsonConvert.SerializeObject(mainClass);
Console.WriteLine(json);
Console.ReadLine();
}
提供您想要的 JSON 结果:
反序列化也可以,利用SecondClassConverter
的ReadJson
方法:
static void Main(string[] args)
{
var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";
var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);
Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
Console.ReadLine();
}
提供输出为:
我有以下class结构
public class MainClass
{
public string MyStringValue {get;set;}
public SecondClass MyClassValue {get;set;}
}
public class SecondClass
{
public string Value {get;set;}
}
我设置了以下值:
SecondClass secondClass = new SecondClass
{
Value = "Test"
}
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
}
当我序列化 class "mainClass" 时,我得到以下 Json (这对我来说绝对清楚):
{
"MyStringValue":"String Value",
"MyClassValue":
{
"Value":"Test"
}
}
有些情况下我想改为序列化为以下内容:
{
"MyStringValue":"String Value",
"MyClassValue": "Test"
}
子class的字段名总是"Value",这怎么办? (而且我还需要对相同的结构进行反序列化)
上面的json和后面的不一样。 Main class 不能在没有转换的情况下序列化为 {"MyStringValue":"String Value","MyClassValue": "Test"}
。
var resultObjet = new {
MyStringValue = mainClass.MyStringValue,
MyClassValue = mainClass.SecondClass.MyClassValue
}
然后就可以序列化了
为此,您需要一个新的 class 进行反序列化。但是对于序列化,您可以即时创建一个匿名类型,如下所示:
void Main()
{
// import Newtonsoft.JsonConvert
SecondClass secondClass = new SecondClass
{
Value = "Test"
};
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
};
// The JSON as you expect
var origJson = JsonConvert.SerializeObject(mainClass);
Console.WriteLine(origJson);
// The JSON Deserialized and the second class value outputted
Console.WriteLine(JsonConvert.DeserializeObject<MainClass>(origJson).MyClassValue.Value);
// The modified JSON as you wanted it
var modJson = JsonConvert.SerializeObject(new { mainClass.MyStringValue, MyClassValue = mainClass.MyClassValue.Value });
Console.WriteLine(modJson);
// The modified JSON deserialized
var deserialized = JsonConvert.DeserializeObject<ModMainClass>(modJson);
Console.WriteLine(deserialized.MyStringValue);
}
public class ModMainClass
{
public string MyStringValue { get; set; }
public string MyClassValue { get; set; }
}
public class MainClass
{
public string MyStringValue {get;set;}
public SecondClass MyClassValue {get;set;}
}
public class SecondClass
{
public string Value { get; set; }
}
你有两个选择,一个是@Simonare提到的
或将 class MainClass
的结构更改为
public class MainClass<T>
{
public string MyStringValue { get; set; }
public T MyClassValue { get; set; }
}
public class SecondClass
{
public string Value { get; set; }
}
现在您可以简单地选择要使用的内容作为 MyClassValue
var c = new MainClass<string>();
或
var c = new MainClass<SecondClass>();
实现此目的的一种方法是使用 Custom JsonConverter with the JsonConverterAttribute。例如,您可以为 class:
创建自定义转换器public class SecondClassConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SecondClass);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
try
{
if (reader.TokenType == JsonToken.String)
{
return new SecondClass
{
Value = reader.Value.ToString()
};
}
}
catch (Exception ex)
{
throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.", ex);
}
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing {nameof(SecondClass)}.");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
var secondClass = (SecondClass)value;
writer.WriteValue(secondClass.Value);
}
}
然后您将 JsonConverterAttribute
与该转换器一起使用:
public class MainClass
{
public string MyStringValue { get; set; }
[JsonConverter(typeof(SecondClassConverter))]
public SecondClass MyClassValue { get; set; }
}
public class SecondClass
{
public string Value { get; set; }
}
这将允许 MainClass
的所有序列化使用 SecondClassConverter
的 WriteJson
方法:
static void Main(string[] args)
{
SecondClass secondClass = new SecondClass
{
Value = "Test"
};
MainClass mainClass = new MainClass
{
MyStringValue = "String Value",
MyClassValue = secondClass
};
var json = JsonConvert.SerializeObject(mainClass);
Console.WriteLine(json);
Console.ReadLine();
}
提供您想要的 JSON 结果:
反序列化也可以,利用SecondClassConverter
的ReadJson
方法:
static void Main(string[] args)
{
var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";
var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);
Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
Console.ReadLine();
}
提供输出为: