2013-11-04 7 views
17

を使用して適切にJSONに変換する列挙型を取得できません:は、私が列挙型を持っているJson.NET

public enum Animal 
{ 
    Dog, 
    Cat, 
    BlackBear 
} 

私は、サードパーティのAPIに送信する必要があります。このAPIでは、送信する列挙値が小文字で、必要に応じてアンダースコアが必要になることが必要です。一般的に、彼らが必要とする名前は、私が使用するenum命名規則と一致しません。 https://gooddevbaddev.wordpress.com/2013/08/26/deserializing-c-enums-using-json-net/に設けた例を使用して

が、私はカスタムJsonConverter使用しようとした:

[JsonProperty("animal")] 
[JsonConverter(typeof(AnimalConverter))] 
public Animal ZooAnimals { get; set; } 
:クラスのプロパティの[戻る

public class AnimalConverter : JsonConverter { 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     var animal = (Animal)value; 
     switch (animal) 
     { 
      case Animal.Dog: 
      { 
       writer.WriteValue("dog"); 
       break; 
      } 
      case Animal.Cat: 
      { 
       writer.WriteValue("cat"); 
       break; 
      } 
      case Animal.BlackBear: 
      { 
       writer.WriteValue("black_bear"); 
       break; 
      } 
     } 
    } 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     var enumString = (string)reader.Value; 
     Animal? animal = null; 
     switch (enumString) 
     { 
      case "cat": 
      { 
       animal = Animal.Cat; 
       break; 
      } 
      case "dog": 
      { 
       animal = Animal.Dog; 
       break; 
      } 
      case "black_bear": 
      { 
       animal = Animal.BlackBear; 
       break; 
      } 
     } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(string); 
    } 
} 

を、私はとても動物に属性を置きます

私はプログラムを実行すると、JsonConverterを完全に無視し、 "black_bear"や "dog"のような期待値を見るのではなく、 "BlackBear"と "Dog"を見ます。 JsonConverterを実際にenum値の名前から、その値を置き換える指定の文字列に変換するにはどうしたらよいですか?

ありがとうございます!

+0

あなたは、短いが完全なプログラムを作ることはできますか?テストする小さなLINQPadプログラムを書いたので、ここでコンバータを使用します。 –

+0

コードサンプルの 'Animal'と' Animals'を参照してください。これらの両方があなたの列挙を参照することを明確にすることはできますか?それは価値があるため、次のスニペットを使用してコードを動作させることができました。 'Zoo zoo = new Zoo {ZooAnimals = Animal.Cat};文字列json = JsonConvert.SerializeObject(zoo); ' – robyaw

答えて

46

独自のコンバータを作成する必要はありません。 Json.NETのStringEnumConverterEnumMember属性を読み取ります。 enumをこれに変更すると、必要な値との間でシリアル化されます。

[JsonConverter(typeof(StringEnumConverter))] 
public enum Animals 
{ 
    [EnumMember(Value = "dog")] 
    Dog, 
    [EnumMember(Value = "cat")] 
    Cat, 
    [EnumMember(Value = "black_bear")] 
    BlackBear 
} 

(マイナー注意点としては、Animalsはフラグ列挙型ではないので、それはshould be singular:。。Animalあなたはこれにそれを変更することを検討すべきである)

+0

こんにちはTim、どうすれば.NET 2.0でEnumMemberを使用できますか? –

+0

@RickyJiao私は 'StringEnumConverter'([ソースを参照)(https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/)に基づいて自分のコンバータを作成したいと思います。 StringEnumConverter.cs)))、EnumMemberAttributeに基づいて自分自身の 'EnumMemberAttribute'クラスで動作させるようにします(ただ一つのプロパティとコンストラクタが必要です)。 –

+0

'StringEnumConverter'がJson.NET' JsonProperty'ではなく 'EnumMember'を使う理由は知っていますか?私は他の場所で 'JsonProperty'を使用していますが、appalantly列挙型では動作しません。 –

0
// Might return null, better to use try catch 
public static Animals GetEnum(string val) 
{ 
    return (Animals)Enum.Parse(typeof(Animals), val, true); 
} 

public static string GetName(Animals an) 
{ 
    return Enum.GetName(typeof(Animals), an); 
} 

public static string GetReplace(Animals an) 
{ 
    var get = GetName(an); 
    var tempstr = ""; 
    int getch = 0; 
    foreach (var chr in get.ToCharArray()) 
    { 
     if (chr == chr.ToUpper()) 
     { 
      getch++; 
      // Second up value char 
      if (getch == 2) 
      { 
       tempstr += "_" + chr; 
      } 
      else 
      { 
       tempstr += chr; 
      } 
     } 
     else 
     { 
      tempstr += chr; 
     } 
    } 
    return tempstr; 
} 
+0

enum値の名前が時々変更されるため、使用できません。例えば、 "BlackBear"というenum値を与えられた場合、 "black_bear"の値を示すように変換する必要があります。 – Xaniff

+0

@Xaniff 'GetEnum(val.Replace(" _ "、" ").Replace(" "、" "));そして編集したものを見る:' GetReplace(animal); ' – 111WARLOCK111

+0

@Xaniff最終値の文字列を使用することはできません。GetReplace(動物).ToLower() ' – 111WARLOCK111

0

私はあなたのConConvert()実装が正しくないと思います。 それは次のようになります。問題を示し、そのインスタンス用(http://linqpad.net)[LINQPad]のためのよう

public override bool CanConvert(Type objectType) 
{ 
    return objectType == typeof(Animals); 
} 
+0

これを文字列からAnimalsに変えようと試みましたが、それでも "black_bear"ではなく "BlackBear"を返します。しかし、ありがとう! – Xaniff

関連する問題