2014-10-03 53 views
0

我想有下面的类定义:C#类来生成JSON收集

[Serializable] 
[CollectionDataContract(Name = "Crowd")] 
public class Crowd : List<Person> 
{ 
} 

[DataContract(Name = "Person")] 
public class Person 
{ 
    public string Name { get; set; } 
    public string Age { get; set; } 
    public string Gender { get; set; } 
} 

,并获得以下JSON:

{ 
    [ 

    {"Name" : "Larry", "Age" : "42", "Gender" : "M"}, 
    {"Name" : "Steve", "Age" : "32", "Gender" : "M"}, 
    {"Name" : "Nancy", "Age" : "22", "Gender" : "F"}, 

    ] 
} 

但我想最终得到这是什么:

{ 
    "Crowd" : 
    [ 
     {"Name" : "Larry", "Age" : "42", "Gender" : "M"}, 
     {"Name" : "Steve", "Age" : "32", "Gender" : "M"}, 
     {"Name" : "Nancy", "Age" : "22", "Gender" : "F"}, 
    ] 
} 

看来,DataContractJsonSerializer类忽略[CollectionDataContract(Name = "Crowd")]属性。 XML序列化按预期工作。

这将工作,但我不想这样定义我的课(去掉类属性显示结构):

public class Root 
{  
    public List<Person> Crowd { get; set;} 
} 

public class Person 
{ 
    public string Name { get; set; } 
    public string Age { get; set; } 
    public string Gender { get; set; } 
} 

任何理由,为什么.NET DataContractJsonSerializer忽略CollectionDataContract属性。任何想法如何我可以强制这个来产生我想要的? XML序列化器工作正常,但我们需要使用JSON。

编辑:所以给出的输入,因此,到目前为止,看来这是我应该为我的JSON(这似乎很有道理):

{ 
    "Crowd" :{ 
    "Person" : 
    [ 
     {"Name" : "Larry", "Age" : "42", "Gender" : "M"}, 
     {"Name" : "Steve", "Age" : "32", "Gender" : "M"}, 
     {"Name" : "Nancy", "Age" : "22", "Gender" : "F"}, 
    ] 
} 
} 

回答

0

与XML这需要一个根元素,JSON的确不需要根元素。整个JSON本身就是根元素,因此不会生成您正在寻找的JSON。

您期望的JSON等同于拥有一个JSON对象,其属性为人群“人群”。但是,这不是代表你的代码的方式。当您序列化一个Crowd对象时,它只是一个人员阵列,这就是序列化器创建的内容。如果您确实需要“人群”属性名称,则没有其他选择,只能像您那样创建包装类Root

+0

感谢RKam。我的研究也指出了这个方向。奇怪的是,JSON不需要根元素,并给出我当前的输出,似乎该集合没有类型属性,只是一堆没有“根”名称的重复列将它们联系在一起。如果有人想要获取该集合,则可能包含任何数量的内容,如“罪犯”,“教师”,“经理”等。 再次感谢您对此主题的意见。 – 2014-10-03 23:31:13

+0

当您将JSON作为表示Javascript对象的方式时,它会变得语义化。你在JSON中表示的是一个Array对象,用另一个属性来表示孩子是次优的。 Javascript本身不支持对象方向,因此一切都是对象。把它想象成序列化一个.NET动态对象。如果你想序列化类型,你应该包含一个显示类型的属性。例子就是像BreezeJS这样的框架,它可以在将.NET数据序列化为Javascript时执行此操作。 – KRam 2014-10-05 02:49:25

1

你没有得到你想要的输出,因为它不是有效的JSON。见JSON.org。 JSON对象(用大括号表示)是名称 - 值对的集合。它不能包含未命名的内容。

如果你把所有的人变成了List<Person>和直接序列化,你可以得到下面的输出,这是有效的JSON:

[ 
    {"Name" : "Larry", "Age" : "42", "Gender" : "M"}, 
    {"Name" : "Steve", "Age" : "32", "Gender" : "M"}, 
    {"Name" : "Nancy", "Age" : "22", "Gender" : "F"}, 
] 

示例代码:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Person> list = new List<Person> 
     { 
      new Person {Name = "Larry", Age = "42", Gender = "M"}, 
      new Person {Name = "Steve", Age = "32", Gender = "M"}, 
      new Person {Name = "Nancy", Age = "22", Gender = "F"}, 
     }; 

     DataContractJsonSerializer ser = 
      new DataContractJsonSerializer(typeof(List<Person>)); 
     MemoryStream ms = new MemoryStream(); 
     ser.WriteObject(ms, list); 

     ms.Position = 0; 
     StreamReader sr = new StreamReader(ms); 
     Console.WriteLine(sr.ReadToEnd()); 
    } 
} 

[DataContract] 
public class Person 
{ 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public string Age { get; set; } 
    [DataMember] 
    public string Gender { get; set; } 
} 
+0

谢谢Brian。我通过注意到我应该使用的替代JSON来编辑我的问题。没有意识到它不是我想要生成的有效JSON对象。鉴于这个新的JSON,我有问题使用通用列表和着名的序列化器来获得我想要的JSON。我得到的是一个以泛型列表类命名的根,并且不是以我的派生类命名的。 类人群:列表 .NET似乎忽略了CollectionDataContract属性。有任何想法吗? – 2014-10-06 22:57:56

+0

通常,您的类结构需要匹配您所需的JSON输出。因此,如果您希望您的JSON拥有包含名为“Crowd”的属性的根对象,该属性是包含Person对象的数组,则需要提供包含名为“Crowd”的成员的根类。既然你在你的问题中说过你不想这样做,我能想到的唯一选择就是切换到不同的序列化程序。如果你使用Json.Net,你可以自定义JsonConverter来做你想做的事。转换器允许类结构与JSON不同。 – 2014-10-08 00:19:44

+0

再次感谢Brian。感谢您在这个话题上的投入和时间。我将按照您最初为我的JSON输出推荐的内容。 – 2014-10-08 17:16:05