简体   繁体   中英

JSON.Net Serialize Collection To Array of Arrays

By default DataTables Ajax expects JSON data to be an array of arrays.

Using JSON.Net is it possible to serialize a collection into an array of arrays instead of an array of objects via an attribute/setting or does it have to be done via a custom JsonConverter . The object I am trying to serialize is as follows:

public class DeviceIndex
{
    public int Id { get; set; }

    [Display(Name = "Asset Tag")]
    public string AssetTag { get; set; }

    [Display(Name = "Lease End")]
    [DataType(DataType.Date)]
    public DateTime LeaseEndDate { get; set; }

    public string Type { get; set; }

    [Display(Name = "Operating System")]
    public string OperatingSystem { get; set; }

    public string Model { get; set; }
}

And my controller action is as follows:

public IActionResult IndexJson()
{
    var model = _db.Devices.Select(d => new DeviceIndex { ... }).ToList();
    return Content(JsonConvert.SerializeObject(new { data = model }), "application/json");
}

Which outputs the JSON:

{
  "data": [
    {
      "Id": 1649,
      ...
    },
    {
      "Id": 703,
      ...
    }
  ]
}

Though my desired results are as follows:

{
  "data": [
    [
      "1649",
      ...
    ],
    [
      "703",
      ...
    ]
  ]
}

I thought I could use the JsonArray attribute for my collection but it doesn't look to change the output.

[JsonArray]
public class DevicesIndex: IEnumerable<DeviceIndex>
{
    List<DeviceIndex> devices;

    public IEnumerator<DeviceIndex> GetEnumerator()
    {
        return devices.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

You can simple way achieve it, just update your IndexJson() method using this simple sample.

You need serialize List<List<object>> , try this sample. This is List of List<string> .

public IActionResult IndexJson()
    {
        List<List<string>> data = new List<List<string>>();

        data.Add(new List<string>(new string[] {"test1", "test2"}));
        data.Add(new List<string>(new string[] {"test3", "test4"}));

        var json = JsonConvert.SerializeObject(new {data = data});
        return Content(json, "application/json");
    }

You will get this JSON

{
  "data":[
    ["test1","test2"],
    ["test3","test4"]
]}

Using Your data model

   List<List<string>> data =new List<List<string>>();

        List<DeviceIndex> deviceIndex = new List<DeviceIndex>();
        DeviceIndex item = new DeviceIndex();
        item.Id = 111;
        item.AssetTag = "Tag";
        item.LeaseEndDate = DateTime.Now;
        item.Type = "Type";
        item.OperatingSystem = "OS";
        item.Model = "Model";

        deviceIndex.Add(item);
        deviceIndex.Add(item);

        foreach (var device in deviceIndex)
        {

            data.Add(new List<string>(new string[] { device.Id.ToString(), device.AssetTag, device.AssetTag, device.OperatingSystem }));
        }

       var json =  JsonConvert.SerializeObject(new {data= data });

JSON

{
 "data":[
   ["111","Tag","Tag","OS"],
   ["111","Tag","Tag","OS"]
  ]
}

It looks like a custom JsonConverter is the suggested method

public class DeviceIndexJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DeviceIndex);
    }

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

    public override void WriteJson(JsonWriter writer, 
                                   object value, 
                                   JsonSerializer serializer)
    {
        if (value == null) return;

        writer.WriteStartArray();

        var properties = value.GetType().GetProperties();
        foreach (var property in properties)
            writer.WriteValue(value.GetType().GetProperty(property.Name).GetValue(value));

        writer.WriteEndArray();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM