簡體   English   中英

序列化為JSON時如何將屬性分組在一起

[英]How to group properties together when serializing to JSON

我有一個平面對象,我想將其分組以簡化解析。 這是我的班級當前情況的基本思想:

class Populations {
  public string US { get; set; }
  public string Canada { get; set; }

  public string Germany { get; set; }
  public string England { get; set; }
}

但這是我希望在填充數據時將其序列化的內容:

{
  "Populations": {
    "North America": {
      "US": "318 million",
      "Canada": "35 million" 
    },
    "Europe": {
      "Germany": "80 million",
      "England": "53 million"
    }
  }
}

我要做的是將我的國家包裹在各大洲之間,而無需實際創建新的大洲類。 是否可以使用Json.Net之類的工具來實現?還是只需要創建具有兩個屬性的NorthAmerica類,然后創建具有兩個屬性的Europe類? 是否有可能存在注釋,以使我可以將其中一些屬性歸為一組?

正如您所描述的,Json.Net中沒有內置的機制可以進行此分組。 但是,如果您確實要這樣做,則可以制作一個自定義JsonConverter來執行此操作。 這樣的事情可能會起作用:

class GroupAttribute : Attribute
{
    public string Name { get; set; }
    public GroupAttribute(string name)
    {
        Name = name;
    }
}

class GroupingConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JObject obj = new JObject();
        Type type = value.GetType();
        foreach (PropertyInfo pi in type.GetProperties())
        {
            JToken propVal = JToken.FromObject(pi.GetValue(value));
            GroupAttribute group = pi.GetCustomAttribute<GroupAttribute>();
            if (group != null)
            {
                JObject groupObj = (JObject)obj[group.Name];
                if (groupObj == null)
                {
                    groupObj = new JObject();
                    obj.Add(group.Name, groupObj);
                }
                groupObj.Add(pi.Name, propVal);
            }
            else
            {
                obj.Add(pi.Name, propVal);
            }
        }

        JObject wrapper = new JObject(new JProperty(type.Name, obj));
        wrapper.WriteTo(writer);
    }

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

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        // CanConvert is not called when a [JsonConverter] attribute is applied
        return false;
    }
}

然后,您可以像這樣標記您的“ Populations類:

[JsonConverter(typeof(GroupingConverter))]
class Populations 
{
    [Group("North America")]
    public string US { get; set; }
    [Group("North America")]
    public string Canada { get; set; }

    [Group("Europe")]
    public string Germany { get; set; }
    [Group("Europe")]
    public string England { get; set; }
}

最后,像這樣序列化:

string json = JsonConvert.SerializeObject(populations, Formatting.Indented);

小提琴: https : //dotnetfiddle.net/EPiJue

您可以創建NorthAmericaEurope類,也可以執行以下操作:

class Continent{
    string Type { get; set; }
    ICollection<Country> Countries { get; set; }
}

當然,這將需要您所有國家/地區擁有共同的基類或接口。

鑒於您的JSON沒有數組,您當前的類使無法創建此json,除非您使用所需的確切結構創建另一個類或將其選擇為動態對象。

如果您必須嚴格遵守此JSON,我建議您制作一個具有以下結構的其他人口類別:

class Populations {
    public NorthAmerica NorthAmerica { get; set; }
    public Europe Europe { get; set; }
}

class NorthAmerica{
    public string US { get; set; }
    public string Canada { get; set; }
}

class Europe{
    public string Germany{ get; set; }
    public string England{ get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM