使属性反序列化但不使用 json.net 序列化 [英] Making a property deserialize but not serialize with json.net

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

问题描述

我们有一些配置文件是通过使用 Json.net 序列化 C# 对象生成的.

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.

一种简单的方法是,将旧的枚举属性保留在类上,并安排 Json.net 在加载配置时读取此属性,但在下一次序列化对象时不再保存它.我们将分别处理从旧枚举生成新类.

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.

是否有任何简单的方法来标记(例如使用属性)C# 对象的属性,以便 Json.net 仅在序列化时忽略它,但在反序列化时关注它?

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

而你想这样做:

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

方法一:添加 ShouldSerialize 方法

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

Approach 1: Add a ShouldSerialize method

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

要使用此功能,请将布尔 ShouldSerializeBlah() 方法添加到您的类中,其中 Blah 替换为您不想序列化的属性的名称.让这个方法的实现总是返回false.

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

注意:如果您喜欢这种方法,但又不想通过引入 ShouldSerialize 方法来混淆类的公共接口,则可以使用 IContractResolver以编程方式做同样的事情.请参阅文档中的条件属性序列化.

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.

不使用 JsonConvert.SerializeObject 进行序列化,而是将配置对象加载到 JObject 中,然后在写出之前从 JSON 中删除不需要的属性.这只是几行额外的代码.

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

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

  1. [JsonIgnore] 属性应用于您不想被序列化的属性.
  2. 向与原始属性类型相同的类添加一个备用的私有属性设置器.将该属性的实现设置为原始属性.
  3. [JsonProperty] 属性应用到备用设置器,为其赋予与原始属性相同的 JSON 名称.
  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.

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

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

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