First of all, please forgive if I am way off on this as I am somewhat new to .net, anonymous types, and LINQ. Frankly I'm struggling a bit and plan to do a lot of learning over the next month on the topic. I know enough to know what I have come up with is not the right way.
I've been given a project to create various delimited output formats deriving from a standard report feed that has been in existence for some time. There is already a framework in place for this and I am simply adding more formats and a few new output mechanisms. (Some of the details that follow are likely irrelevant, but in the interest of clarity I will include.)
A query from the data tier returns an LLBLGEN TypedList. A LINQ query is then applied to create the various feed output formats resulting in an IEnumerable anonymous object. As part of my project I am then to take that object and output it as a comma delimited file.
By reviewing the examples below and some others I've been able to kludge together a working function, but I am certain that it is in no way the right way to accomplish the task (uses reflection, etc.). That said, the "right way" eludes me! Even a pointer in the right direction would be quite helpful.
In c# convert anonymous type into key/value array?
A dictionary where value is an anonymous type in C#
Private Sub SendExport(feed As IEnumerable, filename As String)
Dim delimited As New StringBuilder
Dim type = feed(0).GetType
Dim props = type.GetProperties
delimited.AppendLine(String.Join(",", props.Select(Function(p) p.Name).ToList))
For Each item In feed
Dim itemType = item.GetType
Dim typeProps = itemType.GetProperties
delimited.AppendLine(String.Join(",", typeProps.Select(Function(p) p.GetValue(item)).ToList))
Next
Debug.WriteLine(delimited.ToString)
Response.Clear()
Response.AddHeader("Cache-Control", "must-revalidate")
Response.AddHeader("Pragma", "must-revalidate")
Response.AddHeader("Content-type", "application/vnd.ms-excel")
Response.AddHeader("Content-disposition", String.Format("attachment; filename={0}.csv", filename))
Response.Write(delimited.ToString)
Response.End()
End Sub