2012-10-19 12 views
0

我想使用json.net爲jquery ui小部件序列化選項,例如, jquery手風琴。具有兩個可爲空屬性的json.net對象序列化爲單個屬性

但是手風琴有一個屬性活性它可以是以下之一:

基於整數0限定的有源標籤,

布爾值,當設置爲假,將摺疊所有手風琴。

我想創建2個可空的.NET屬性:

int? Active 

bool? IsActive 

如果當前不爲空,應該序列化與屬性名的整數活躍, 如果IsActive不爲空應該是序列化爲具有相同名稱的布爾型活動。 .Net代碼將確保只有其中一個不能爲空。

但是,當我把兩個屬性[JsonProperty(「active」)],它不工作...任何替代?

回答

0

你目前的做法的困難在於讓這兩個字段不起作用,因爲你不能將它們標記爲[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); 
+0

你的解決方案是好的,但我一直在尋找(如果可能的話,當然)一個更通用的方法,因爲我想序列化其他的jQuery UI部件的選擇也是如此。我有點害怕,我將不得不添加大量的轉換器,適用於所有不同的情況。 – rekna

+0

轉換器的數量取決於你想要序列化的其他控件 - 這種方法的唯一原因是active屬性既是布爾值又是整數:你可能不一定對其他控件有這個問題。此外,你可以非常高興地在其他布爾/整數場景中重用'ActiveTabConverter';它不是特定於「活動」屬性。 –

+0

不幸的是,在jquery小部件中有幾個屬性可以接受多種數據類型,而不僅僅是整數/布爾值 – rekna

相關問題