带有属性类型的序列化属性名称的问题

时间:2014-02-13 06:17:36

标签: c# json json.net

使用Netonsoft.Json和ASP.Net Web API。

我必须生成一个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属性名称应使用其类型。

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:1)

你可以创建一个自定义的Json转换器来做任何你想做的事情,无论你想要什么。 就像描述here

一样

在write方法中,只需检查对象的类型,并相应地对其进行序列化。

答案 1 :(得分: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();

您需要一个具有View属性的根对象,该属性是一个视图列表...

public class RootObject 
{
    public List<View> View { get; set; }
}

答案 2 :(得分:0)

您可以通过为JsonConverter类制作自定义View来解决此问题:

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

然后使用View属性装饰您的[JsonConverter]课程:

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

您的示例缺少一个用于保存视图列表的容器类,因此我假设它看起来像这样:

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"
      }
    }
  ]
}