制作一个属性反序列化,但不与json.net连载 [英] Making a property deserialize but not serialize with json.net

查看:178
本文介绍了制作一个属性反序列化,但不与json.net连载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有这是由序列C#对象与Json.net产生了一些配置文件。

我们想序列化类的一个属性远从一个简单枚举财产成一个类属性迁移。

一个简单的方法来做到这一点,将是保留旧枚举属性的类,并安排Json.net读取此属性,当我们加载的配置,而不​​是再次保存它,当我们下一个序列化对象。我们将处理来自旧枚举分别产生新的类。

有没有简单的方法来标记(例如带属性)一个C#对象的属性,因此,当序列化将Json.net只忽略它,但反序列化时,要注意呀?


解决方案

有其实你可以用它来达到你想要的结果几个非常简单的方法。

让我们假设,例如,你有你的类目前是这样定义的:

 类配置
{
    公共菲斯ObsoleteSetting {搞定;组; }
    公共邦ReplacementSetting {搞定;组; }
}枚举菲斯{阿尔法,贝塔,伽玛}邦级
{
    公共字符串值{获得;组; }
}

和你想做到这一点:

  JSON字符串= @{ObsoleteSetting:伽玛,};//反序列化
配置配置= JsonConvert.DeserializeObject<配置>(JSON);//迁移
config.ReplacementSetting =
    新浜{值= config.ObsoleteSetting.ToString()};//连载
JSON = JsonConvert.SerializeObject(配置);
Console.WriteLine(JSON);

要得到这样的:

  {ReplacementSetting:{值:伽玛}}

方法1:添加ShouldSerialize方法

Json.NET必须通过寻找类对应的 ShouldSerialize 方法有条件序列化属性的能力。

要使用此功能,添加一个布尔值 ShouldSerializeBlah()法类,其中胡说将被替换为命名你不想序列化的属性。使此方法的实现总是返回

 类配置
{
    公共菲斯ObsoleteSetting {搞定;组; }    公共邦ReplacementSetting {搞定;组; }    公共BOOL ShouldSerializeObsoleteSetting()
    {
        返回false;
    }
}

请注意:如果你喜欢这种方法,但你不希望通过引入 ShouldSerialize 方法泥泞你的类的公有接口,可以使用 IContractResolver 做同样的事情编程。请参见条件属性序列化的文件中。

方法2:JObjects操纵JSON

而不是使用 JsonConvert.SerializeObject 来做到系列化,配置对象加载到 JObject ,然后简单地写出来之前从JSON不需要的属性。这只是一对夫妇的code的额外的行。

  JObject祚= JObject.FromObject(配置);//删除从其父ObsoleteSettingJProperty
乔[ObsoleteSetting] Parent.Remove()。JSON = jo.ToString();

方法3:聪​​明(AB)属性的使用


  1. 套用 [JsonIgnore] 属性,你不想被序列化的属性。

  2. 添加备用,私人的属性setter与相同类型的原始属性的类。使该财产的执行设置原始属性。

  3. 套用 [JsonProperty] 属性到备用二传手,给它相同的JSON的名称与原始属性。

下面是修订后的配置类:

 类配置
{
    [JsonIgnore]
    公共菲斯ObsoleteSetting {搞定;组; }    [JsonProperty(ObsoleteSetting)]
    私人菲斯ObsoleteSettingAlternateSetter
    {
        //得到的是故意省略
        集合{ObsoleteSetting =价值; }
    }    公共邦ReplacementSetting {搞定;组; }
}

We have some configuration files which were generated by serializing C# objects with Json.net.

We'd like to migrate one property of the serialised class away from being a simple enum property into a class property.

One easy way to do this, would be to leave the old enum property on the class, and arrange for Json.net to read this property when we load the config, but not to save it again when we next serialize the object. We'll deal with generating the new class from the old enum separately.

Is there any simple way to mark (e.g. with attributes) a property of a C# object, so that Json.net will ignore it ONLY when serializing, but attend to it when deserializing?

解决方案

There are actually several fairly simple approaches you can use to achieve the result you want.

Let's assume, for example, that you have your classes currently defined like this:

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

enum Fizz { Alpha, Beta, Gamma }

class Bang
{
    public string Value { get; set; }
}

And you want to do this:

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);

To get this:

{"ReplacementSetting":{"Value":"Gamma"}}

Approach 1: Add a ShouldSerialize method

Json.NET has the ability to conditionally serialize properties by looking for corresponding ShouldSerialize methods in the class.

To use this feature, add a boolean ShouldSerializeBlah() method to your class where Blah is replaced with the name of the property that you do not want to serialize. Make the implementation of this method always return false.

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

    public Bang ReplacementSetting { get; set; }

    public bool ShouldSerializeObsoleteSetting()
    {
        return false;
    }
}

Note: if you like this approach but you don't want to muddy up the public interface of your class by introducing a ShouldSerialize method, you can use an IContractResolver to do the same thing programmatically. See Conditional Property Serialization in the documentation.

Approach 2: Manipulate the JSON with JObjects

Instead of using JsonConvert.SerializeObject to do the serialization, load the config object into a JObject, then simply remove the unwanted property from the JSON before writing it out. It's just a couple of extra lines of code.

JObject jo = JObject.FromObject(config);

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

json = jo.ToString();

Approach 3: Clever (ab)use of attributes

  1. Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.
  2. Add an alternate, private property setter to the class with the same type as the original property. Make the implementation of that property set the original property.
  3. Apply a [JsonProperty] attribute to the alternate setter, giving it the same JSON name as the original property.

Here is the revised Config class:

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; }
}

这篇关于制作一个属性反序列化,但不与json.net连载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆