I have an object:
public class SiteInfo
{
public string Title { get; set; }
public string URL { get; set; }
public string Type { get; set; }
}
That I am using to create a list: var sites = new List();
foreach (SPWeb site in web.GetSubwebsForCurrentUser())
{
string sitetype = getConfigurationKey(site, "siteType");
//If sites have a site type then add to list
if (sitetype != "*ERROR*" && sitetype != "*KEYNOTFOUND*")
{
SiteInfo s = new SiteInfo();
s.Title = site.Title;
s.URL = site.Url;
s.Type = sitetype;
sites.Add(s);
}
}
//sort list by type
sites.Sort((x, y) => string.Compare(x.Type, y.Type));
// serialize and send..
JavaScriptSerializer serializer = new JavaScriptSerializer();
StringBuilder sbJsonResults = new StringBuilder();
serializer.Serialize(sites, sbJsonResults);
etc.....
However what I would like to do is group the sites by Type prior to serializing them. Is this possible using LINQ or some other method.
It sounds like you want something like:
// No need to sort sites first
var grouped = sites.OrderBy(x => x.Type)
.GroupBy(x => x.Type);
Then just serialize grouped
. However, I don't know quite what an IGrouping
will look like in JSON... and the type will be present in each case. You may want something like:
var grouped = sites.OrderBy(x => x.Type)
.GroupBy(x => x.Type)
.Select(g => new { Type = g.Key,
Sites = g.Select(site => new {
site.Title,
site.URL
} });
I think that would give you a nicer JSON structure.
This
var sites = new List<SiteInfo>()
{
new SiteInfo(){Title="1",Type="a",URL="http://aaaa"},
new SiteInfo(){Title="2",Type="b",URL="http://bbbb"},
new SiteInfo(){Title="3",Type="a",URL="http://aaaa"},
new SiteInfo(){Title="4",Type="b",URL="http://bbb"},
};
var json = new JavaScriptSerializer().Serialize(sites.GroupBy(s => s.Type));
would produce
[
[{"Title":"1","URL":"http://aaaa","Type":"a"},{"Title":"3","URL":"http://aaaa","Type":"a"}],
[{"Title":"2","URL":"http://bbbb","Type":"b"},{"Title":"4","URL":"http://bbb","Type":"b"}]
]
or
var json = new JavaScriptSerializer().Serialize(sites.GroupBy(s => s.Type)
.ToDictionary(x=>x.Key,x=>x));
would produce
{
"a":[{"Title":"1","URL":"http://aaaa","Type":"a"},{"Title":"3","URL":"http://aaaa","Type":"a"}],
"b":[{"Title":"2","URL":"http://bbbb","Type":"b"},{"Title":"4","URL":"http://bbb","Type":"b"}]
}
Here's a straightforward console application that does what you want:
static void Main(string[] args)
{
List<SiteInfo> sites = new List<SiteInfo>()
{
new SiteInfo() { Title = "Site A", Type = "Whatever 2" },
new SiteInfo() { Title = "Site B", Type = "Whatever 1" },
new SiteInfo() { Title = "Site C", Type = "Whatever 1" },
new SiteInfo() { Title = "Site D", Type = "Whatever 3" },
new SiteInfo() { Title = "Site E", Type = "Whatever 3" }
};
var sitesGroupedByType =
sites.GroupBy(s => s.Type).Select(g => new { Type = g.Key,
Sites = g.Select(site => new
{
site.Title,
site.URL
})});
foreach (var siteTypeGroup in sitesGroupedByType.OrderBy(g => g.Type))
{
foreach(var site in siteTypeGroup.Sites)
{
Console.WriteLine(string.Format("Type => {0}, Title => {1}",
siteTypeGroup.Type, site.Title));
}
}
Console.ReadKey();
}
Output:
Type => Whatever 1, Title => Site B
Type => Whatever 1, Title => Site C
Type => Whatever 2, Title => Site A
Type => Whatever 3, Title => Site D
Type => Whatever 3, Title => Site E
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With