你目前的做法的困難在於讓這兩個字段不起作用,因爲你不能將它們標記爲[JsonProperty("active")]
。我第一次嘗試是定義類,如下所示:
class Accordion
{
[JsonProperty("active")]
[JsonConverter(typeof(ActiveTabConverter))]
public int Active { get; set; }
[JsonProperty("active")]
[JsonConverter(typeof(ActiveTabConverter))]
public bool IsActive { get; set; }
}
導致,因爲我對兩個屬性使用[JsonProperty("active")]
異常(我相信你有這個爲好)。刪除其中的一個屬性也不起作用:沒有例外,但該屬性被刪除的字段從未被反序列化。
什麼做的工作是如下:
class Accordion
{
[JsonProperty("active")]
[JsonConverter(typeof(ActiveTabConverter))]
public int Active { get; set; }
[JsonIgnore]
public bool IsActive
{
get
{
return this.Active > -1;
}
}
public Accordion()
{
this.Active = -1;
}
}
注意,還有兩個領域,但只有其中一人將被反序列化。 IsActive
是一個幫手屬性。我在這裏遵循的約定是,大於0的Active
值表示開放式手風琴選項卡,而-1相當於從JSON接收false
。
class ActiveTabConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(int) || objectType == typeof(bool);
}
public override object ReadJson(JsonReader reader, Type objectType,
JsonSerializer serializer)
{
var value = JValue.ReadFrom(reader);
if (value.Type == JTokenType.Integer)
{
return serializer.Deserialize<int>(reader);
}
return -1;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
int item = (int)value;
if (item == -1)
{
writer.WriteValue(false);
}
else
{
writer.WriteValue(item);
}
writer.Flush();
}
}
該類負責反序列化和序列化Active
值。
我使用以下代碼來序列化/反序列化。請注意,JSON實際上來自jQuery手風琴。對於所涉及的一個屬性來說是過度的,但我認爲最好使用真實數據。
string json1 = "{\"disabled\":false,\"create\":null,\"active\":2,\"animate\":300,\"collapsible\":false,\"event\":\"click\",\"header\":\"> li > :first-child,> :not(li):even\",\"heightStyle\":\"auto\",\"icons\":{\"activeHeader\":\"ui-icon-triangle-1-s\",\"header\":\"ui-icon-triangle-1-e\",\"headerSelected\":\"ui-icon-triangle-1-s\"},\"activate\":null,\"beforeActivate\":null,\"navigation\":false,\"autoHeight\":true,\"clearStyle\":false,\"fillSpace\":false,\"change\":null,\"changestart\":null,\"animated\":\"slide\"}";
string json2 = "{\"disabled\":false,\"create\":null,\"active\":false,\"animate\":300,\"collapsible\":true,\"event\":\"click\",\"header\":\"> li > :first-child,> :not(li):even\",\"heightStyle\":\"auto\",\"icons\":{\"activeHeader\":\"ui-icon-triangle-1-s\",\"header\":\"ui-icon-triangle-1-e\",\"headerSelected\":\"ui-icon-triangle-1-s\"},\"activate\":null,\"beforeActivate\":null,\"navigation\":false,\"autoHeight\":true,\"clearStyle\":false,\"fillSpace\":false,\"change\":null,\"changestart\":null,\"animated\":\"slide\"}";
Accordion accordion = JsonConvert.DeserializeObject<Accordion>(json1);
string serializedJson = JsonConvert.SerializeObject(accordion);
accordion = JsonConvert.DeserializeObject<Accordion>(json2);
serializedJson = JsonConvert.SerializeObject(accordion);
你的解決方案是好的,但我一直在尋找(如果可能的話,當然)一個更通用的方法,因爲我想序列化其他的jQuery UI部件的選擇也是如此。我有點害怕,我將不得不添加大量的轉換器,適用於所有不同的情況。 – rekna
轉換器的數量取決於你想要序列化的其他控件 - 這種方法的唯一原因是active屬性既是布爾值又是整數:你可能不一定對其他控件有這個問題。此外,你可以非常高興地在其他布爾/整數場景中重用'ActiveTabConverter';它不是特定於「活動」屬性。 –
不幸的是,在jquery小部件中有幾個屬性可以接受多種數據類型,而不僅僅是整數/布爾值 – rekna