如何将List 转换为特定的Json格式

我希望能够将List转换为特定的JSON表格式。 在我的例子中, T将始终是一个简单的对象(没有嵌套属性)。 这里有两个例子来说明我想要的东西。

示例#1:将List列为JSON

 // C# list of Persons var list = new List() { new Person() { First = "Jesse", Last = "Gavin", Twitter = "jessegavin" }, new Person() { First = "John", Last = "Sheehan", Twitter = "johnsheehan" } }; // I want to transform the list above into a JSON object like so { columns : ["First", "Last", "Twitter"], rows: [ ["Jesse", "Gavin", "jessegavin"], ["John", "Sheehan", "johnsheehan"] ] } 

示例#2: List

到JSON

 // C# list of Locations var list = new List() { new Location() { City = "Los Angeles", State = "CA", Zip = "90210" }, new Location() { City = "Saint Paul", State = "MN", Zip = "55101" }, }; // I want to transform the list above into a JSON object like so { columns : ["City", "State", "Zip"], rows: [ ["Los Angeles", "CA", "90210"], ["Saint Paul", "MN", "55101"] ] } 

有没有办法告诉JSON.net以这种方式序列化对象? 如果没有,我怎么能做到这一点? 谢谢。

更新:

感谢@ Hightechrider的回答,我能够编写一些解决问题的代码。

您可以在此处查看工作示例https://gist.github.com/1153155

使用reflection,您可以获得该类型的属性列表:

  var props = typeof(Person).GetProperties(); 

给定Person p的实例,您可以获得属性值的枚举:

  props.Select(prop => prop.GetValue(p, null)) 

用通用方法包装它们,添加你最喜欢的Json序列化,你就拥有了你想要的格式。

假设你使用.Net 4这应该做你想要的一切。 该类实际上允许您转换为XML或JSON。 CommunicationType的Enum位于底部。 如果您传递的类已使用DataContract和DataMember属性进行修饰,则序列化程序的效果最佳。 我在底部加了一个样本。 它也将采用匿名类型,只要它是所有简单类型。

reflection也可以工作但是你必须理解输出复杂数据类型的所有JSON细微差别等。这使用了.Net 4中的内置JSON序列化器。还有一点需要注意,因为JSON没有定义日期类型.Net将日期放在一个时髦的ASP.Net自定义格式中。 只要使用内置反序列化器进行反序列化,它就可以正常工作。 如果需要,我可以挖掘相关文档。

 using System; using System.Xml.Serialization; using System.Text; using System.Runtime.Serialization.Json; using System.IO; using System.Xml.Linq; internal class Converter { public static string Convert(T obj, CommunicationType format, bool indent = false, bool includetype = false) { if (format == CommunicationType.XML) { return ToXML(obj, includetype, indent); } else if (format == CommunicationType.JSON) { return ToJSON(obj); } else { return string.Empty; } } private static string ToXML(T obj, bool includetype, bool indent = false) { if (includetype) { XElement xml = XMLConverter.ToXml(obj, null, includetype); if(indent) { return xml.ToString(); } else { return xml.ToString(SaveOptions.DisableFormatting); } } else { System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces(); XmlSerializer xs = new XmlSerializer(typeof(T)); StringBuilder sbuilder = new StringBuilder(); var xmlws = new System.Xml.XmlWriterSettings() { OmitXmlDeclaration = true, Indent = indent }; ns.Add(string.Empty, string.Empty); using (var writer = System.Xml.XmlWriter.Create(sbuilder, xmlws)) { xs.Serialize(writer, obj, ns); } string result = sbuilder.ToString(); ns = null; xs = null; sbuilder = null; xmlws = null; return result; } } private static string ToJSON(T obj) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream()) { string result = string.Empty; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); ser.WriteObject(ms, obj); result = encoding.GetString(ms.ToArray()); ms.Close(); encoding = null; ser = null; return result; } } } [DataContract()] public enum CommunicationType : int { [XmlEnum("0"), EnumMember(Value = "0")] XML = 0, [XmlEnum("1"), EnumMember(Value = "1")] JSON = 1 } [DataContract(Namespace = "")] public partial class AppData { [DataMember(Name = "ID")] public string ID { get; set; } [DataMember(Name = "Key")] public string Key { get; set; } [DataMember(Name = "Value")] public string Value { get; set; } [DataMember(Name = "ObjectType")] public string ObjectType { get; set; } } 

您不需要标准格式的任何具体原因?

要真正回答这个问题:

由于这是JSON语法之外的东西,我想不出在默认框架中实现它的方法。

一种解决方案是利用属性来装饰您希望通过有线属性传输的属性,并使用Reflection循环遍历属性并输出其属性名称作为列标题,然后循环抛出对象并写入值。 通用性足以使其可以应用于其他对象。

 public class Location { [JsonFooAttribute("City")] public string city {get;set;} [JsonFooAttribute("State")] public string state {get;set;} }