2013-08-31 61 views
16

tôi đã liệt kê một định nghĩa với C#, nơi tôi đang lưu trữ nó là giá trị như nhân vật, như thế này:Deserialize nhân vật json như liệt kê

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

Tôi đang cố gắng để deserialize sử dụng JSON.NET, nhưng đến JSON được viết bằng cách sử dụng giá trị cHAR (string) thay vì giá trị int thuộc kiểu liệt kê, như thế này:

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

có thể xác định một số loại chuyển đổi mà sẽ cho phép tôi tự phân tích các char để enum giá trị?

Tôi đã thử tạo JsonConverter, nhưng không chắc chắn cách thực hiện, trong khi chỉ áp dụng cho thuộc tính này chứ không phải toàn bộ đối tượng được phân tích cú pháp. dưới đây là những gì tôi đã thử:

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

Logic có thể sai và tôi có thể khắc phục nhưng vấn đề là ReadJson() không được gọi.

CanConvert là, nhưng nó dường như kêu gọi tất cả các tài sản, không chỉ là một tài sản tôi xác định nó cho:

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

Tôi chắc rằng tôi đã làm điều này không đúng nhưng đang gặp khó khăn khi tìm tài liệu về cách thực hiện việc này cho một trường duy nhất ...

Tôi đang thiếu gì?

+0

Bạn có thể gửi một lớp mẫu trong đó có 'sở hữu CardType' nơi deserilization thất bại? – nemesv

+0

u có thể đăng enum hoàn chỉnh. Tôi chắc chắn bạn không thể khai báo enum như bạn đã xác định ở trên – dharam

+0

lớp được deserialized vào chỉ có một tài sản CardType để nhận được giá trị deserialized, không có gì trong đó khác với tuyên bố. Đối với giá trị enum, đó thực sự là định nghĩa đầy đủ của ENUM. lớp Card có một thuộc tính kiểu CardType để lưu trữ giá trị kiểu liệt kê. – SelAromDotNet

Trả lời

16

Bạn làm nhu cầu không cần thiết một tùy chỉnh JsonConverter bạn có thể sử dụng được xây dựng trong StringEnumConverter với sự kết hợp của EnumMemberAttribute (từ việc lắp ráp System.Runtime.Serialization).

Nếu không có EnumMemberAttribute, hãy sử dụng tên enum để Nghệ sĩ, Đương đại, v.v. vì vậy bạn cần phải đổi tên với giá trị A, C, v.v.

Nhưng nó không phải là giải pháp đẹp nhất bởi vì bạn phải lặp lại giá trị của bạn hai lần, nhưng nó hoạt động:

[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 điều này trông giống như một giải pháp lý tưởng, và nó chắc chắn hoạt động tuyệt vời, cảm ơn bạn! – SelAromDotNet

+1

Làm thế nào để deserialize trên? tôi đang gặp sự cố trong quá trình deserializing điều này. Ex: Dịch vụ có enum này: [EnumMember (Value = "Contemp")] Đương đại = 'C', mã UI có enum này: [EnumMember (Value = "Contemp")] Đương đại = 'C ' Vì vậy, trong khi deserializing, nó không thể tìm thấy "Contemp" .. Có cách nào để làm điều đó? hoặc chỉ trao đổi Enum và Value thành, [EnumMember (Value = "ontemporary")] Contemp = 'C', –

3

Mã này hoạt động hoàn hảo:

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

Cập nhật:
gì về out-of-box StringEnumConverter:

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

yep, tôi xin lỗi tôi đã sai, JSON không được tạo ra bởi một serialization, đó là một chuỗi JSON tùy chỉnh, sử dụng giá trị char thay vì int. xin vui lòng xem mô tả cập nhật và cảm ơn bạn đã giúp đỡ của bạn! – SelAromDotNet

0

Bạn có thể chỉ cần thêm SerializerSettings.Converters.Add (StringEnumConverter mới());

đến lớp BrowserJsonFormatter bạn

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