2014-02-13 25 views
1

正在使用Netonsoft.Json和ASP.Net Web API。使用屬性類型序列化PropertyName的問題

我必須生成如下面JSON字符串,

"view": 
[ 
{"id": "MAIN_TOP_IMAGE_b", 
    "image": 
    { 
     "value": "Base64 encoding(image.jpg)", 
     "type": "jpg;base64", 
     "align": "right" 
    } 
}, 
{"id": "MAIN_BARCODE_a", 
    "barcode": 
    { 
     "value": " 32455232453", 
     "type": "QRCODE", 
     "caption": "1432343fdoadkfe" 
    } 
} 
] 

我已經創建了一個類作爲下面,

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

public class Image 
{ 
    [JsonProperty("value")] 
    public string Value { get; set; } 

    [JsonProperty("type")] 
    public string Type { get; set; } 

    [JsonProperty("align")] 
    public string Align { get; set; } 

    [JsonProperty("bgcolor")] 
    public string BGColor { get; set; } 
} 

public class Text 
{ 
    [JsonProperty("value")] 
    public string Value { get; set; } 

    [JsonProperty("color")] 
    public string Color { get; set; } 

    [JsonProperty("align")] 
    public string Align { get; set; } 
} 

public class Barcode 
{ 
    [JsonProperty("value")] 
    public string Value { get; set; } 

    [JsonProperty("type")] 
    public string Type { get; set; } 

    [JsonProperty("caption")] 
    public string Caption { get; set; } 
} 

鑑於elementData中將會具有的對象之一(圖像,條形碼,文本) elementdata屬性名稱應使用其類型。

有沒有辦法做到這一點?

回答

0

您可以通過自定義JsonConverterView類是這樣解決這個問題:

[JsonConverter(typeof(ViewConverter))] 
public class View 
{ 
    [JsonProperty("id")] 
    public string Id { get; set; } 
    public Object ElementData { get; set; } 
} 

你的例子丟失:

class ViewConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(View)); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     View view = (View)value; 
     JObject jo = new JObject(); 
     jo.Add("id", view.Id); 
     if (view.ElementData != null) 
     { 
      jo.Add(view.ElementData.GetType().Name.ToLower(), 
        JObject.FromObject(view.ElementData)); 
     } 
     jo.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

然後用[JsonConverter]屬性這樣的裝點你的View類一個容器類來保存視圖列表,所以我假設它看起來像這樣:

public class RootObject 
{ 
    [JsonProperty("view")] 
    public List<View> Views { get; set; } 
} 

所有這些作品的地方,你可以序列化RootObject得到你想要的JSON:

class Program 
{ 
    static void Main(string[] args) 
    { 
     RootObject obj = new RootObject(); 
     obj.Views = new List<View> 
     { 
      new View 
      { 
       Id = "MAIN_TOP_IMAGE_b", 
       ElementData = new Image 
       { 
        Value = "Base64 encoding(image.jpg)", 
        Type = "jpg;base64", 
        Align = "right" 
       } 
      }, 
      new View 
      { 
       Id = "MAIN_BARCODE_a", 
       ElementData = new Barcode 
       { 
        Value = " 32455232453", 
        Type = "QRCODE", 
        Caption = "1432343fdoadkfe" 
       } 
      } 
     }; 

     string json = JsonConvert.SerializeObject(obj, Formatting.Indented); 
     Console.WriteLine(json); 
    } 
} 

輸出:

{ 
    "view": [ 
    { 
     "id": "MAIN_TOP_IMAGE_b", 
     "image": { 
     "value": "Base64 encoding(image.jpg)", 
     "type": "jpg;base64", 
     "align": "right", 
     "bgcolor": null 
     } 
    }, 
    { 
     "id": "MAIN_BARCODE_a", 
     "barcode": { 
     "value": " 32455232453", 
     "type": "QRCODE", 
     "caption": "1432343fdoadkfe" 
     } 
    } 
    ] 
} 
+0

謝謝Brian。它像一個魅力。是的,我沒有說明你提到的額外班級。 – SVP

+0

很高興你發現它有幫助。 –

0

可能能得到你想要什麼繼承...

public abstract class View 
{ 
    public string Id { get; set; } 
} 

public class ImageView : View 
{ 
    public Image Image { get; set; } 
} 

public class BarcodeView : View 
{ 
    public Barcode Barcode { get; set; } 
} 

public class TextView : View 
{ 
    public Text Text { get; set; } 
} 

根據this article,你只需要配置Json.net串用正確的類型名稱和移交它應該工作...

// WebApiConfig.cs 

var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); 
jsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects; 

// use camelCase resolver to do away with the JsonProperty annotations 
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

您需要的是有一個的意見列表的視圖屬性根對象...

​​
+0

不太。 TypeNameHandling = TypeNameHandling.Objects使序列化程序爲JSON層次結構中的每個對象輸出名稱爲$ type的附加屬性。它不會根據它的類型更改現有屬性的名稱,這是問題中要求的。 –

0

你可以創建一個自定義的Json轉換器來做任何你想做的事,你想怎麼做。 就像描述的here

在寫入方法中,只需檢查對象的類型,並相應地序列化它。