2

Json.NET を使用してシリアル化しようとしているプロパティがいくつかあります。複雑なオブジェクトは、[JsonProperty("name")] 属性だけを上に置く必要があるため、正常に機能します。

残念ながら、これを列挙型で機能させるのに苦労しています。理想的には、次のように言うだけでプロパティを定義できるようにしたいと考えています。

MyValue = ThisEnum.First;

クラス内のプロパティに、列挙型を適切な変更された値の名前に自動的にシリアル化させます (この質問が尋ねたように:属性による (逆) シリアル化中に列挙型の値の形式を制御します。残念ながら、私はいくつかのカスタム コンバーターを作成し、適用しようとしました。以前の質問の 1 つ ( Json.NET を使用して enum を適切に json に変換することができません) の人々の提案と、そのスレッドの回答者がうまくいくように見える回答をしているにもかかわらず、私の解決策ではそうではありません。何の効果もありません。

たとえば、次のプロパティ クラスがあるとします。

public class Animal
{
    [JsonProperty("id")]
    public string Id {get;set;}

    [JsonProperty("types")]
    [JsonConverter(typeof(StringEnumConverter))]
    public AnimalType Types {get;set;}

    [JsonProperty("created")]
    [JsonConverter(typeof(MyDateTimeToSecondsSinceEpochConverter))]
    public DateTime Created {get;set;}
}

AnimalType 列挙内:

public enum AnimalType
{
    [EnumMember(Value="black_rhino")]
    BlackRhino,
    [EnumMember(Value="wild_pig")]
    WildPig,
    [EnumMember(Value="chicken")]
    Chicken
}

MyDateTimeToSecondsSinceEpochConverter クラス内:

public class MyDateTimeToSecondsSinceEpochConverter : DateTimeConverterBase
{
    public override WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRawValue(@"""\/Date(" + ConvertDateTimeToEpoch((DateTime)value).ToString() + @")\/""");
    }

    public override ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null) return null;
        if (reader.TokenType == JsonToken.Integer)
            return ConvertEpochToDateTime((long)reader.Value);
        return DateTime.Parse(reader.Value.ToString());
    }

    public DateTime ConvertEpochToDateTime(long seconds)
    {
        return new DateTime(1970, 1, 1).AddSeconds(seconds);
    }

    public long ConvertDateTimeToEpoch(DateTime dateTime)
    {
        var epochStart = new DateTime(1970,1,1);
        if (dateTime < epochStart) return 0;
        return Convert.ToInt64(dateTime.Subtract(epochStart).TotalSeconds);
    }
}

私の呼び出し方法では、次のようなものを使用できます。

var data  = new Animal {
    Id = "123abc",
    Types = AnimalType.BlackRhino,
    Created = new DateTime(2014,3,15)
}

オブジェクトの各プロパティと、値の HTML エンコード出力を一覧表示し、それらすべてを文字列 (後で URL に添付します) に入れるという単純な意図で、オブジェクトの各プロパティをステップスルーする方法を使用します。 ):

public static string GetString(Animal animal)
{
    var result = "";
    foreach( var property in animal.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
    {
        foreach(var attribute in property.GetCustomAttributes(false))
        {
            var name = (JsonPropertyAttribute)attribute;
            var value = property.GetValue(animal, null);
            if (value != null)
            {
                if (!string.Empty(result))
                    result += "&";
                result += string.Format("{0}={1}", name.PropertyName, HttpUtility.UrlEncode(value.ToString()));
            }
        }
    }
    return result;
}

残念ながら、これを実行すると、次のように表示されます。

'id=abc123&type=BlackRhino&created=3%2f15%2f2014+12%3a00%3a00+AM'

2つの JsonConverters を実際に変換する方法について、誰かアイデアはありますか? JsonProperty の名前は明らかに変更されていますが、「BlackRhino」は「black_rhino」に変更されておらず、DateTime も long に変換されていません。

理想的には、属性の土地で何かを探しているか、これらのコンバーターを使用しているので、将来プロジェクトで使用するすべての列挙型に対して get/set を記述する必要はありませんが、属性を適用するだけで完了できますそれと。

ありがとう!

4

1 に答える 1