使属性反序列化但不使用json.net序列化

威尔·迪恩

我们有一些配置文件是通过使用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"}}

方法1:添加ShouldSerialize方法

Json.NET可以通过ShouldSerialize在类中查找相应的方法来有条件地序列化属性

若要使用此功能,请ShouldSerializeBlah()向您的类中添加一个boolean方法,该类中的方法将Blah替换为您不想序列化的属性的名称。使此方法的执行始终返回false

class Config
{
    public Fizz ObsoleteSetting { get; set; }

    public Bang ReplacementSetting { get; set; }

    public bool ShouldSerializeObsoleteSetting()
    {
        return false;
    }
}

注意:如果您喜欢这种方法,但又不想通过引入一种ShouldSerialize方法弄混类的公共接口,则可以使用anIContractResolver来以编程方式执行相同的操作。请参阅文档中的条件属性序列化

方法2:使用JObjects处理JSON

无需使用JsonConvert.SerializeObject序列化方法,JObject只需将config对象加载到中,然后在将其写出之前从JSON中删除不需要的属性即可。这只是几行额外的代码。

JObject jo = JObject.FromObject(config);

// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();

json = jo.ToString();

方法3:巧妙(滥用)属性使用

  1. [JsonIgnore]属性应用于您不想序列化的属性。
  2. 向该类添加一个替代的私有属性设置器,其类型与原始属性相同。使该属性的实现设置为原始属性。
  3. [JsonProperty]属性应用于替代设置器,为其赋予与原始属性相同的JSON名称。

这是修改后的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; }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章