c# – 使一个属性反序列化,但不与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()方法,其中Blah将替换为您不想序列化的属性的名称。使该方法的实现总是返回false。

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

    public Bang ReplacementSetting { get; set; }

    public bool ShouldSerializeObsoleteSetting()
    {
        return false;
    }
}

注意:如果你喜欢这种方法,但是你不想通过介绍一个ShouldSerialize方法来混淆你的类的公共接口,你可以使用IContractResolver以编程方式做同样的事情。请参阅文档中的Conditional Property Serialization

方法2:使用JObjects处理JSON

而不是使用JsonConvert.SerializeObject做序列化,加载配置对象到一个JObject,然后简单地从JSON中删除不需要的属性,然后写出来。它只是一对额外的代码行。

JObject jo = JObject.FromObject(config);

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

json = jo.ToString();

方法3:聪明(ab)使用属性

>将[JsonIgnore]属性应用于不希望序列化的属性。
>向类中添加与原始属性相同类型的备用,私有属性设置器。使该属性的实现设置原始属性。
>将[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; }
}

转载注明原文:c# – 使一个属性反序列化,但不与json.net序列化 - 代码日志