問(wèn)題描述
我們有一些配置文件是通過(guò)使用 Json.net 序列化 C# 對(duì)象生成的.
We have some configuration files which were generated by serializing C# objects with Json.net.
我們希望將序列化類的一個(gè)屬性從簡(jiǎn)單的枚舉屬性遷移到類屬性中.
We'd like to migrate one property of the serialised class away from being a simple enum property into a class property.
一種簡(jiǎn)單的方法是,將舊的枚舉屬性保留在類上,并安排 Json.net 在加載配置時(shí)讀取此屬性,但在下一次序列化對(duì)象時(shí)不再保存它.我們將分別處理從舊枚舉生成新類.
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.
是否有任何簡(jiǎn)單的方法來(lái)標(biāo)記(例如使用屬性)C# 對(duì)象的屬性,以便 Json.net 僅在序列化時(shí)忽略它,但在反序列化時(shí)關(guān)注它?
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?
推薦答案
實(shí)際上,您可以使用幾種相當(dāng)簡(jiǎn)單的方法來(lái)實(shí)現(xiàn)您想要的結(jié)果.
There are actually several fairly simple approaches you can use to achieve the result you want.
假設(shè),例如,您的類當(dāng)前定義如下:
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);
要得到這個(gè):
{"ReplacementSetting":{"Value":"Gamma"}}
方法一:添加 ShouldSerialize 方法
Json.NET 能夠通過(guò)在類中查找相應(yīng)的 ShouldSerialize
方法來(lái)有條件地序列化屬性.
Approach 1: Add a ShouldSerialize method
Json.NET has the ability to conditionally serialize properties by looking for corresponding ShouldSerialize
methods in the class.
要使用此功能,請(qǐng)將布爾 ShouldSerializeBlah()
方法添加到您的類中,其中 Blah
替換為您不想序列化的屬性的名稱.讓這個(gè)方法的實(shí)現(xiàn)總是返回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;
}
}
注意:如果您喜歡這種方法,但又不想通過(guò)引入 ShouldSerialize
方法來(lái)混淆類的公共接口,則可以使用 IContractResolver
以編程方式做同樣的事情.請(qǐng)參閱文檔中的條件屬性序列化.
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
進(jìn)行序列化,而是將配置對(duì)象加載到 JObject
中,然后在寫(xiě)出之前從 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)使用屬性
- 將
[JsonIgnore]
屬性應(yīng)用于您不想被序列化的屬性. - 向與原始屬性類型相同的類添加一個(gè)備用的私有屬性設(shè)置器.將該屬性的實(shí)現(xiàn)設(shè)置為原始屬性.
- 將
[JsonProperty]
屬性應(yīng)用到備用設(shè)置器,為其賦予與原始屬性相同的 JSON 名稱.
- Apply a
[JsonIgnore]
attribute to the property that you do not want to be serialized. - 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.
- 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; }
}
這篇關(guān)于使屬性反序列化但不使用 json.net 序列化的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!