Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化为JSON时如何将属性分组在一起_C#_Json.net - Fatal编程技术网

C# 序列化为JSON时如何将属性分组在一起

C# 序列化为JSON时如何将属性分组在一起,c#,json.net,C#,Json.net,我有一个平面对象,我想将其分组为多个部分,以便更容易地进行解析。这是我的班级目前的基本情况: class Populations { public string US { get; set; } public string Canada { get; set; } public string Germany { get; set; } public string England { get; set; } } 但这就是我希望在填充数据时将其序列化为的内容: { "Popu

我有一个平面对象,我想将其分组为多个部分,以便更容易地进行解析。这是我的班级目前的基本情况:

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
类?是否存在允许我将这些属性组合在一起的注释?

您可以创建类
北美
欧洲
,或者执行以下操作:

class Continent{
    string Type { get; set; }
    ICollection<Country> Countries { get; set; }
}
类大陆{
字符串类型{get;set;}
i收集国家{get;set;}
}

当然,这需要所有国家都有一个共同的基类或接口。

您可以创建类
北美
欧洲
,或者您可以执行以下操作:

class Continent{
    string Type { get; set; }
    ICollection<Country> Countries { get; set; }
}
类大陆{
字符串类型{get;set;}
i收集国家{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; }
}

鉴于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; }
}

在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;
    }
}
最后,按如下方式序列化:

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

Fiddle:

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;
    }
}
最后,按如下方式序列化:

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

Fiddle:

将我的国家包装成大陆
地图功能在哪里…使用一个包含
名称
的类数组
国家
人口
大陆
属性。
将我的国家/地区包装成大陆
地图函数在哪里…使用具有
名称
的类数组
国家
人口
大陆
属性。这难道不会序列化为与他想要的json稍有不同的东西吗?他的json似乎暗示他希望北美拥有美国和加拿大的财产。您建议的大陆类在序列化时会使它们成为一个数组,对吗?@JaredDrake这与JSON不同,但他也说“这就是我要做的”。两者都不能直接实现他的目标,但是……是的,我明白你的意思。他将不得不给出他的JSON或生成/修改类。这难道不会序列化成与他想要的JSON稍有不同的东西吗?他的json似乎暗示他希望北美拥有美国和加拿大的财产。您建议的大陆类在序列化时会使它们成为一个数组,对吗?@JaredDrake这与JSON不同,但他也说“这就是我要做的”。两者都不能直接实现他的目标,但是……是的,我明白你的意思。他将不得不放弃JSON或制作/修改类。你确定
群体的属性吗<代码>德国
或欧洲
@Eser修复了它。谢谢您确定人口的属性吗<代码>德国
或欧洲
@Eser修复了它。谢谢