2013-08-31 16 views
16

mam wyliczenie zdefiniowane w C#, gdzie jestem przechowującej to wartości jak bohaterów, tak:Cofnięcie json charakter jako wyliczenie

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

Ja próbuje deserializowania użyciu Json.NET, ale przychodzącego JSON został napisany przy użyciu wartości cHAR (string) zamiast wartości iNT wyliczenia, tak:

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

Czy to możliwe, aby zdefiniować jakiś konwerter który pozwoli mi ręcznie analizowania char do wyliczenia wartość?

Próbowałem utworzyć JsonConverter, ale nie jestem pewien jak to zrobić, stosując go tylko do tej właściwości, a nie do całego analizowanego obiektu. oto co próbowałem:

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

logika może być źle i mogę to naprawić, ale problem jest ReadJson() nie jest wywoływana w ogóle.

CanConvert jest, ale wydaje się być wywołana dla każdej nieruchomości, a nie tylko jedną właściwość zdefiniowałem go:

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

Jestem pewien, że zrobiłem to nieprawidłowo, ale mam problem ze znalezieniem dokumentacji jak to zrobić dla pojedynczego pola ...

Czego mi brakuje?

+0

można umieścić klasy próbki, która ma właściwość 'CardType' gdzie deserilization powiedzie? – nemesv

+0

można opublikować pełne wyliczenie. Jestem pewien, że nie można zadeklarować wyliczenia, jak zdefiniowałeś powyżej – dharam

+0

, gdy klasa jest deserializowana, ma tylko właściwość CardType, aby odebrać przekształconą wartość, nie ma tam niczego poza deklaracją. Jeśli chodzi o wartość wyliczeniową, jest to rzeczywiście pełna definicja ENUM. klasa Card ma właściwość typu CardType do przechowywania wyliczonej wartości typu. – SelAromDotNet

Odpowiedz

16

Robisz nie konieczną potrzebę zwyczaj JsonConverter można użyć wbudowany StringEnumConverter z kombinacją EnumMemberAttribute (z zestawu System.Runtime.Serialization).

Bez nazwy EnumMemberAttribute używa nazw wyliczeniowych, więc Artysta, Współczesny itp., Więc musisz zmienić nazwy z nim na wartość A, C, itp.

Ale nie jest to najładniejszy rozwiązanie bo trzeba powtórzyć wartości dwa razy, ale to działa:

[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

Wow to wygląda na idealne rozwiązanie i na pewno działa świetnie, dziękuję! – SelAromDotNet

+1

Jak deserializować powyższy? Mam problemy z deserializacją tego. Np Obsługa ma ten wyliczenia: [EnumMember (wartość = "Contemp")] Contemporary = 'C', kod UI tego wyliczenia: [EnumMember (wartość = "Contemp")] Contemporary = „C ' Tak więc, podczas deserializacji, nie można znaleźć "Contemp" .. Czy jest jakiś sposób to zrobić? lub po prostu zamień Enum i wartość na, [EnumMember (Wartość = "współczesna")] Contemp = 'C', –

3

Ten kod działa perfekcyjnie:

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

Aktualizacja:
Co o out-of-box StringEnumConverter:

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

Tak, przykro mi, że się mylę, JSON nie jest generowany przez serializację, jest to niestandardowy ciąg JSON, który używa wartości char zamiast int. zobacz zaktualizowany opis i dziękuję za pomoc! – SelAromDotNet

0

Można tylko dodać SerializerSettings.Converters.Add (nowa StringEnumConverter());

do klasy 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"); 
    } 
}