2013-08-31 17 views
16

として、私は、私はこのように、それは文字などの値です保存していますC#ので定義された列挙、持っている:デシリアライズJSON文字列挙

public enum CardType 
{ 
    Artist = 'A', 
    Contemporary = 'C', 
    Historical = 'H', 
    Musician = 'M', 
    Sports = 'S', 
    Writer = 'W' 
} 

私はJSON.NETを使用してデシリアライズしようとしたが、入ってくるんだがJSONはこのように、CHAR値(文字列)の代わりに、列挙のint型の値を使用して書かれていた:

[{"CardType","A"},{"CardType", "C"}] 

それは私が手動で列挙に文字を解析することを可能にするコンバータのいくつかの種類を定義することは可能です値?

私はJsonConverterを作成しようとしましたが、それを行う方法がわかりません。このプロパティにのみ適用され、解析されたオブジェクト全体には適用されません。

public class EnumerationConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
     { 
      return null; 
     } 

     int value = serializer.Deserialize<int>(reader); 
     return (CardType)value; 
    } 

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

ロジックが間違っているかもしれないと私はそれを修正することができますが、問題は全く呼び出されていないReadJson()である:ここで私が試したものです。

CanConvertがあるが、私はそれを定義していないだけで一つの特性、すべてのプロパティのために呼ばれるように表示されます。

public class Card 
{ 
      private CardType type; 
     [JsonConverter(typeof(EnumerationConverter))] 
     public CardType Type 
     { 
      get { return type; } 
      set { type = value; } 
     } 
} 

私は私が間違ってこれをやったと確信しているが、トラブルのドキュメントを見つけることが生じています1つのフィールドでこれを行う方法について...

私は何が欠けていますか?

+0

あなたはdeserilizationが失敗した 'CardType'プロパティを持つサンプルクラスを投稿することができますか? – nemesv

+0

は完全なenumを投稿できます。上記で定義したようにenumを宣言できないと確信しています。 – dharam

+0

デシリアライズされるクラスには、デシリアライズされた値を受け取るCardTypeプロパティがあります。宣言以外には何もありません。列挙型の値は、実際にはENUMの完全な定義です。 Cardクラスには、列挙型の値を格納するためのCardType型のプロパティがあります。 – SelAromDotNet

答えて

16

あなたが使用することができますJsonConverterカスタムの必要は必要ありませんEnumMemberAttributeSystem.Runtime.Serializationアセンブリから)の組み合わせでStringEnumConverterに組み込まれています。

EnumMemberAttributeがなければ、Artist、Contemporaryなどのようにenum名が使用されるため、名前をA、Cなどの値に変更する必要があります。

しかし、あなたは自分の価値観を2回繰り返す必要があるため、それは素敵なソリューションではありませんが、それは動作します:

[JsonConverter(typeof(StringEnumConverter))] 
public enum CardType 
{ 
    [EnumMember(Value = "A")] 
    Artist = 'A', 
    [EnumMember(Value = "C")] 
    Contemporary = 'C', 
    [EnumMember(Value = "H")] 
    Historical = 'H', 
    [EnumMember(Value = "M")] 
    Musician = 'M', 
    [EnumMember(Value = "S")] 
    Sports = 'S', 
    [EnumMember(Value = "W")] 
    Writer = 'W' 
} 
+0

これは理想的なソリューションのように見えますが、それは間違いなく素晴らしいことです。ありがとうございます! – SelAromDotNet

+1

上記のものを逆シリアル化する方法は? これをデシリアライズする際に問題が発生しています。 例: [EnumMember(値= "Contemp")] UIコードはこの列挙有する 現代= 'C': [EnumMember(値= "Contempを")] 現代=「C サービスは、この列挙を有します' デシリアライズ中に、「Contemp」を見つけることができません。これを行う方法はありますか?列挙型と値を交換して [EnumMember(値= "ontemporary")] Contemp = 'C'、 –

3

このコードは完璧に動作します:

CardType[] array = { CardType.Artist, CardType.Contemporary }; 
string s = JsonConvert.SerializeObject(array); 
var array2 = JsonConvert.DeserializeObject<CardType[]>(s); 

更新
何アウトオブボックスStringEnumConverterについて:

[JsonConverter(typeof(StringEnumConverter))] 
public CardType Type { get; set; } 
+0

あまりにも申し訳ありませんが、JSONはシリアル化によって生成されていません。更新された説明を参照していただき、ありがとうございます! – SelAromDotNet

0

あなただけSerializerSettings.Converters.Add(新しいStringEnumConverterを())を追加することができます。

あなたBrowserJsonFormatterクラスへ

public class BrowserJsonFormatter : JsonMediaTypeFormatter 
{ 
    public BrowserJsonFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); 
     SerializerSettings.Formatting = Formatting.Indented; 
     SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 
     SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
     SerializerSettings.Converters.Add(new EmptyToNullConverter()); 
     SerializerSettings.Converters.Add(new StringEnumConverter()); 
     //SerializerSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; 
    } 

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) 
    { 
     base.SetDefaultContentHeaders(type, headers, mediaType); 
     headers.ContentType = new MediaTypeHeaderValue("application/json"); 
    } 
} 
関連する問題