我们有一些配置文件,这些文件是通过使用Json.net序列化C#对象而生成的。
我们希望将序列化类的一个属性从简单的枚举属性迁移到类属性。
一种简单的方法是将旧的enum属性保留在类中,并安排Json.net在加载配置时读取此属性,但在下次序列化对象时不再保存它。我们将处理从旧枚举分别生成新类的问题。
有没有简单的方法来标记(例如,带有属性)C#对象的属性,以便Json.net仅在序列化时将其忽略,而在反序列化时将对其进行关注?
实际上,可以使用几种相当简单的方法来获得所需的结果。
例如,假设您当前定义了这样的类:
class Config { public Fizz ObsoleteSetting { get; set; } public Bang ReplacementSetting { get; set; } } enum Fizz { Alpha, Beta, Gamma } class Bang { public string Value { get; set; } }
而您想这样做:
string json = @"{ ""ObsoleteSetting"" : ""Gamma"" }"; // deserialize Config config = JsonConvert.DeserializeObject<Config>(json); // migrate config.ReplacementSetting = new Bang { Value = config.ObsoleteSetting.ToString() }; // serialize json = JsonConvert.SerializeObject(config); Console.WriteLine(json);
为了得到这个:
{"ReplacementSetting":{"Value":"Gamma"}}
Json.NET可以通过ShouldSerialize在类中查找相应的方法来有条件地序列化属性。
ShouldSerialize
若要使用此功能,请ShouldSerializeBlah()在您的类中添加一个布尔方法,该方法将Blah替换为您不想序列化的属性的名称。使此方法的执行始终返回false。
ShouldSerializeBlah()
Blah
false
class Config { public Fizz ObsoleteSetting { get; set; } public Bang ReplacementSetting { get; set; } public bool ShouldSerializeObsoleteSetting() { return false; } }
注意:如果您喜欢这种方法,但又不想通过引入一种ShouldSerialize方法弄混类的公共接口,则可以使用an IContractResolver来以编程方式执行相同的操作。请参阅文档中的条件属性序列化。
IContractResolver
无需使用JsonConvert.SerializeObject序列化方法,JObject只需将config对象加载到中,然后在将其写出之前从JSON中删除不需要的属性即可。这只是几行额外的代码。
JsonConvert.SerializeObject
JObject
JObject jo = JObject.FromObject(config); // remove the "ObsoleteSetting" JProperty from its parent jo["ObsoleteSetting"].Parent.Remove(); json = jo.ToString();
[JsonIgnore]
[JsonProperty]
这是修改后的Config类:
Config
class Config { [JsonIgnore] public Fizz ObsoleteSetting { get; set; } [JsonProperty("ObsoleteSetting")] private Fizz ObsoleteSettingAlternateSetter { // get is intentionally omitted here set { ObsoleteSetting = value; } } public Bang ReplacementSetting { get; set; } }