0

json.netを使用して、jqueryuiウィジェットのオプション(jqueryアコーディオンなど)をシリアル化したい。

ただし、アコーディオンにはアクティブなプロパティがあり、次のいずれかになります。

アクティブなタブを定義する整数0ベース。

ブール値をfalseに設定すると、すべてのアコーディオンが折りたたまれます。

私は2つのnull許容の.NETプロパティを作成することを考えていました:

int? Active

bool? IsActive

Activeがnullでない場合は、プロパティ名がactiveの整数としてシリアル化する必要があります。IsActiveがnullでない場合は、同じ名前がactiveのブール値としてシリアル化する必要があります。.Netコードは、そのうちの1つだけがnullにならないようにします。

しかし、両方のプロパティに[JsonProperty( "active")]を配置すると、機能しません...他の方法はありますか?

4

1 に答える 1

0

現在のアプローチの難しさは、両方をマークできないため、これらの 2 つのフィールドが機能しないことです[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")]私は2つのプロパティで使用したため、これにより例外が発生します(これも同様に発生したと思います) 。これらの属性の 1 つを削除しても機能しませんでした。例外はありませんでしたが、属性が削除されたフィールドは逆シリアル化されませんでした。

うまくいったのは次のとおりです。

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

まだ 2 つのフィールドがありますが、そのうちの 1 つだけが逆シリアル化されることに注意してください。はIsActiveヘルパー プロパティです。ここで従った規則はActive、0 より大きい値は開いているアコーディオン タブを示し、-1 はfalseJSON からの受信に相当するというものです。

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 アコーディオンから取得されることに注意してください。問題の 1 つのプロパティについてはやり過ぎですが、実際のデータを使用するのが最善だと思いました。

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);
于 2012-10-20T03:50:32.513 に答える