I wrote a method which exports values to excel file from an IEnumerable parameter. Method worked fine for my little test class and i was happy till i test my method with a LINQ class.
Method:
public static void IEnumerableToExcel<T>(IEnumerable<T> data, HttpResponse Response)
{
Response.Clear();
Response.ContentEncoding = System.Text.Encoding.Default;
Response.Charset = "windows-1254";
// set MIME type to be Excel file.
Response.ContentType = "application/vnd.ms-excel;charset=windows-1254";
// add a header to response to force download (specifying filename)
Response.AddHeader("Content-Disposition", "attachment;filename=\"ResultFile.xls\"");
Type typeOfT = typeof(T);
List<string> result = new List<string>();
FieldInfo[] fields = typeOfT.GetFields();
foreach (FieldInfo info in fields)
{
result.Add(info.Name);
}
Response.Write(String.Join("\t", result.ToArray()) + "\n");
foreach (T t in data)
{
result.Clear();
foreach (FieldInfo f in fields)
result.Add((typeOfT).GetField(f.Name).GetValue(t).ToString());
Response.Write(String.Join("\t", result.ToArray()) + "\n");
}
Response.End();
}
My Little Test Class:
public class Mehmet
{
public string FirstName;
public string LastName;
}
Two Usage:
Success:
Mehmet newMehmet = new Mehmet();
newMehmet.FirstName = "Mehmet";
newMehmet.LastName = "Altiparmak";
List<Mehmet> list = new List<Mehmet>();
list.Add(newMehmet);
DeveloperUtility.Export.IEnumerableToExcel<Mehmet>(list, Response);
Fa开发者_运维知识库il:
ExtranetDataContext db = new ExtranetDataContext();
DeveloperUtility.Export.IEnumerableToExcel<User>(db.Users, Response);
Fail Reason: When the code reaches the code block used to get the fields of the template(T), it can not find any field for the LINQ Generated User class. For my weird class it works fine.
Why?
Thanks...
Classes generated by LINQ to SQL store the data in private fields (whose name starts with underscore), while your sample class exposes the data in public fields. The overload of the GetFields
method that you are using returns only public fields, so it will work for your class, but not for LINQ to SQL generated classes.
A good practice in .NET is to expose data as public properties, so the best way to correct your method would be to switch from using fields to using properties. You'll need to change GetFields
to GetProperties
(which returns PropertyInfo[]
). Then it will work for LINQ to SQL generated classes and for classes that you write like this (using automatic properties in C# 3.0):
public class Mehmet {
public string FirstName { get; set; }
public string LastName { get; set; }
}
Alternatively, you could use both GetFields
and GetProperties
, but since a well designed class should not contain public fields, this shouldn't be needed.
Also, your nested foreach uses GetField
in a slightly weird way:
foreach (FieldInfo f in fields)
result.Add((typeOfT).GetField(f.Name).GetValue(t).ToString());
// You don't need 'GetFied' because 'f' is the field you're looking for:
foreach (FieldInfo f in fields)
result.Add(f.GetValue(t).ToString());
For PropertyInfo
, this will look the same (you'll only use PropertyInfo
instead).
精彩评论