user1640256
user1640256

Reputation: 1719

Iterating a collection and creating a nested object

I have a model that looks like:

public class SearchResult
{
    public bool success { get; set; }
    public SearchData data { get; set; }
}

public class SearchData 
{
    public string UploadDate { get; set; }
    public List<UserImages> Images { get; set; }
}

public class UserImages
{
    public string Filename { get; set; }
    public string FileId { get; set; }
}

My collection is returning result in the following format

FileId  FileName    UploadDate
148847  IMG_1.JPG   Mar-2012
135710  IMG_8.JPG   Mar-2012
143817  IMG_6.JPG   Jul-2013
143873  IMG_5.JPG   Aug-2014
145766  IMG_4.JPG   Aug-2015
145820  IMG_3.JPG   Jan-2016
145952  IMG_2.JPG   Jan-2016

I want to serialize the above collection so that I can generate the following JSON:

{
    "success": true,
    "SearchData": {
        "UploadDate": "MAR-2012",
        "UserImages": [{
            "Filename": "IMG_1.JPG",
            "FileId ": "148847"
        }, {
            "Filename": "IMG_8.JPG",
            "FileId ": "135710"
        }],
        "UploadDate": "Jul-2013",
        "UserImages": [{
            "Filename": "IMG_6.JPG",
            "FileId ": "143817"
        }]
    }
}

I just can't get the iteration working. How can I iterate the collection to create the object of my model class to serialize it later?

Upvotes: 0

Views: 215

Answers (3)

Derpy
Derpy

Reputation: 1528

This sounds like a classic group by question. Here is a self-contained example that should copy-paste compile into any test class.

public class SearchResult
{
    public bool success { get; set; }
    public SearchData data { get; set; }
}

public class SearchData
{
    public string UploadDate { get; set; }
    public IEnumerable<UserImages> Images { get; set; }
}

public class UserImages
{
    public string Filename { get; set; }
    public string FileId { get; set; }
}

public class FlatData
{
    public string Id { get; set; }
    public string Name { get; set; }
    public DateTime Date { get; set; }
}

public static void Test()
{
    //generate arbitrary dates to group on
    var dates = Enumerable.Range(0, 3).Select(x => DateTime.Today.AddDays(x)).ToArray();
    //generate some sample data in the flat format
    var flatData = Enumerable.Range(1, 10).Select(x => new FlatData() { Id = x.ToString(), Name = "Image_" + x, Date = dates[x % 3] });

    //group the flat data into the hierarchical format
    var grouped = from item in flatData
                  group item by item.Date into g
                  select new SearchData()
                  {
                      UploadDate = g.Key.ToShortDateString(),
                      Images = from img in g
                               select new UserImages()
                               {
                                   FileId = img.Id,
                                   Filename = img.Name
                               }
                  };

    //Serialization implementation abstracted, as it should be
    var json = Common.Helper.SerializeJSON(grouped);
}}

Sample json output:

[
   {
      "UploadDate":"7/27/2016",
      "Images":[
         {
            "Filename":"Image_1",
            "FileId":"1"
         },
         {
            "Filename":"Image_4",
            "FileId":"4"
         },
         {
            "Filename":"Image_7",
            "FileId":"7"
         },
         {
            "Filename":"Image_10",
            "FileId":"10"
         }
      ]
   },
   {
      "UploadDate":"7/28/2016",
      "Images":[
         {
            "Filename":"Image_2",
            "FileId":"2"
         },
         {
            "Filename":"Image_5",
            "FileId":"5"
         },
         {
            "Filename":"Image_8",
            "FileId":"8"
         }
      ]
   },
   {
      "UploadDate":"7/26/2016",
      "Images":[
         {
            "Filename":"Image_3",
            "FileId":"3"
         },
         {
            "Filename":"Image_6",
            "FileId":"6"
         },
         {
            "Filename":"Image_9",
            "FileId":"9"
         }
      ]
   }
]

Upvotes: 1

Gilad Green
Gilad Green

Reputation: 37299

This will turn your collection into that object model that you can then serialize to JSON.

var result = new SearchResult
{
    Success = true,
    SearchData = results.GroupBy(item => item.UploadDate, 
               (key, grouping) => new SearchData 
               { 
                    UploadDate = key, 
                    Images = grouping.Select(item => new UserImage
                    {
                        FileName = item.FileName,
                        FileId = item.FileId 
                    }).ToList() 
               } ).ToList()
};

var json = new JavaScriptSerializer().Serialize(result);
var json_otherWay = Newtonsoft.Json.JsonConvert.SerializeObject(result);

Notice though that SearchData is a collection and not a single item like in your code above:

public class SearchResult
{
    public bool Success { get; set; }
    public List<SearchData> Data { get; set; }
}

The JSON part I took from here

Upvotes: 2

Abins C
Abins C

Reputation: 1

Try this.

using Newtonsoft.Json;

public class SearchData 
{
    public string UploadDate { get; set; }
    public List<UserImages> Images { get; set; }
    public bool success { get; set; }
}

public class UserImages
{
    public string Filename { get; set; }
    public string FileId { get; set; }
}

var result= JsonConvert.DeserializeObject<List<SearchData>>("JsonString")

Upvotes: 0

Related Questions