我有一个包含项目列表的类。 当我序列化类时,我希望项目索引值出现在 JSON 中。
我使用以下代码转换为 JSON:
var json = Newtonsoft.Json.JsonConvert.SerializeObject(imp);
现在我得到的输出如下所示:
{
"userdata":{
"name":"name",
"type":"type",
"company_name":"company_name"
},
"f_item":null,
"o_item":null,
"attributes":[
{
"firstval":"0",
"name":"at 0",
"opposite_name":"opname 0"
},
{
"firstval":"1",
"name":"at 1",
"opposite_name":"opname 1"
},
{
"firstval":"2",
"name":"at 2",
"opposite_name":"opname 2"
},
{
"firstval":"3",
"name":"at 3",
"opposite_name":"opname 3"
},
{
"firstval":"4",
"name":"at 4",
"opposite_name":"opname 4"
}
],
"eos":null
}
我需要这样的输出:
{
"userdata":{
"name":"name",
"type":"type",
"company_name":"company_name"
},
"f_item":null,
"o_item":null,
"attributes":{
"0": {
"firstval":"0",
"name":"at 0",
"opposite_name":"opname 0"
},
"1": {
"firstval":"1",
"name":"at 1",
"opposite_name":"opname 1"
},
"2": {
"firstval":"2",
"name":"at 2",
"opposite_name":"opname 2"
},
"3": {
"firstval":"3",
"name":"at 3",
"opposite_name":"opname 3"
},
"4": {
"firstval":"4",
"name":"at 4",
"opposite_name":"opname 4"
}
},
"eos":null
}
如何配置 Json.Net 以输出索引值?
与其尝试将 Json.Net 配置为以非标准方式输出数据,不如尝试使用正确的数据结构。作为一种更简单的解决方案,请使用字典来存储数组的内容。Json.Net 会将其解释为对象,并将每个键用作其属性。
var originalArray = new [] {
new { Foo = "first", Bar = "abc" },
new { Foo = "second", Bar = "def" },
new { Foo = "third", Bar = "ghi" },
new { Foo = "fourth", Bar = "jkl" }
};
var data = originalArray
.Select((value, index) => new { value, index })
.ToDictionary(wrapper => wrapper.index, wrapper => wrapper.value);
var json = JsonConvert.SerializeObject(data);
此示例代码将输出以下 JSON,这正是您想要的:
{
"0": {"Foo":"first", "Bar":"abc"},
"1": {"Foo":"second", "Bar":"def"},
"2": {"Foo":"third", "Bar":"ghi"},
"3": {"Foo":"fourth", "Bar":"jkl"}
}
如果类中有项列表,但需要将 JSON 输出格式化为具有索引属性的对象(而不是数组),则可以使用自定义JsonConverter
在序列化期间将列表转换为对象。
这是转换器的外观。 这将适用于任何实现ICollection
,包括列表和数组。
class ListToObjectConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(ICollection).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JObject jo = new JObject();
int index = 0;
foreach (object item in (ICollection)value)
{
jo.Add(index.ToString(), JToken.FromObject(item, serializer));
index++;
}
jo.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
若要使用转换器,请将 [JsonConverter]
属性添加到类中的 attributes
属性,如下所示:
[JsonConverter(typeof(ListToObjectConverter))]
public List<Attribute> attributes { get; set; }
然后,只需像往常一样序列化,您将获得所需的输出。 这是一个演示:
class Program
{
static void Main(string[] args)
{
RootObject imp = new RootObject
{
userdata = new UserData
{
name = "name",
type = "type",
company_name = "company_name"
},
attributes = new List<Attribute>
{
new Attribute
{
firstval = "0",
name = "at 0",
opposite_name = "oppname 0"
},
new Attribute
{
firstval = "1",
name = "at 1",
opposite_name = "oppname 1"
},
new Attribute
{
firstval = "2",
name = "at 2",
opposite_name = "oppname 2"
}
}
};
var json = JsonConvert.SerializeObject(imp, Formatting.Indented);
Console.WriteLine(json);
}
}
public class RootObject
{
public UserData userdata { get; set; }
public object f_item { get; set; }
public object o_item { get; set; }
[JsonConverter(typeof(ListToObjectConverter))]
public List<Attribute> attributes { get; set; }
public object eos { get; set; }
}
public class UserData
{
public string name { get; set; }
public string type { get; set; }
public string company_name { get; set; }
}
public class Attribute
{
public string firstval { get; set; }
public string name { get; set; }
public string opposite_name { get; set; }
}
输出:
{
"userdata": {
"name": "name",
"type": "type",
"company_name": "company_name"
},
"f_item": null,
"o_item": null,
"attributes": {
"0": {
"firstval": "0",
"name": "at 0",
"opposite_name": "oppname 0"
},
"1": {
"firstval": "1",
"name": "at 1",
"opposite_name": "oppname 1"
},
"2": {
"firstval": "2",
"name": "at 2",
"opposite_name": "oppname 2"
}
},
"eos": null
}