views:

17

answers:

1

I am confused on how can I use generic methods to parse generic list into datatable/dataset. My setup: 1. I have a class Customers defined in WCF Service Library.

namespace Wcf.Sample.ServiceLibrary
{
    public class Customers
    {
        public string ID = string.Empty;
        public string CompanyName = string.Empty;
        public string ContactName = string.Empty;
    }
}

2. I use this class to return a generic list from my OperationContract.

namespace Wcf.Sample.ServiceLibrary
{
    [ServiceContract]
    public interface ICustomerService
    {
        [OperationContract]
        List<Customers> GetAllCustomers();
    }       
}

3. Consume WCF Service in web client page. On button click I populate the GridView with the list returned from GetAllCustomers(). This works perfectly fine.

GridView1.DataSource = client.GetAllCustomers();
GridView1.DataBind();

4. Now the issue is, for some reason (sort/paging function) I want to actually convert the returned generic list into a datatable. To do so, I have a method that returns me a datatable which I want to bind to a GridView. Here are the methods:

public static DataTable ConvertTo<T>(System.Collections.Generic.List<T> genericList)
{
    //create DataTable Structure
    DataTable dataTable = CreateTable<T>();
    Type entType = typeof(T);
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
    //get the list item and add into the list
    foreach (T item in genericList)
    {
        DataRow row = dataTable.NewRow();
        foreach (PropertyDescriptor prop in properties)
        {
            row[prop.Name] = prop.GetValue(item);
        }
        dataTable.Rows.Add(row);
    }
    return dataTable;
}

public static DataTable CreateTable<T>()
{
    //T –> ClassName
    Type entType = typeof(T);
    //set the datatable name as class name
    DataTable dataTable = new DataTable(entType.Name);
    //get the property list
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
    foreach (PropertyDescriptor prop in properties)
    {
        //add property as column
        dataTable.Columns.Add(prop.Name, prop.PropertyType);
    }
    return dataTable;
}

I am not sure how to call this function? How can I specify the as Customers class which is actually in a webservice? Totally lost. I would appreciate if someone can guide me on the following code, how to make it work.

GridView1.DataSource = ConvertTo<???>(client.GetAllCustomers());
A: 

I was able to resolve this issue by modifing the WCF Service itself (although I was reluctant to do so). I modified the GetAllCustomers method to return a datatable instead of generic type. In the service itself, I am converting the generic type into datatable using the same methods:

public static DataTable ConvertTo<T>(System.Collections.Generic.List<T> genericList) 
{ 
    //create DataTable Structure 
    DataTable dataTable = CreateTable<T>(); 
    Type entType = typeof(T); 
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType); 
    //get the list item and add into the list 
    foreach (T item in genericList) 
    { 
        DataRow row = dataTable.NewRow(); 
        foreach (PropertyDescriptor prop in properties) 
        { 
            row[prop.Name] = prop.GetValue(item); 
        } 
        dataTable.Rows.Add(row); 
    } 
    return dataTable; 
} 

public static DataTable CreateTable<T>() 
{ 
    //T –> ClassName 
    Type entType = typeof(T); 
    //set the datatable name as class name 
    DataTable dataTable = new DataTable(entType.Name); 
    //get the property list 
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType); 
    foreach (PropertyDescriptor prop in properties) 
    { 
        //add property as column 
        dataTable.Columns.Add(prop.Name, prop.PropertyType); 
    } 
    return dataTable; 
}

Another thing that I noticed is that the following line

PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);

would always returned null for my type. This was due to the fact that I didn't have any get/set methods in Customers class. I created get/set methods in Customer class and everything worked like a charm.

Thanks to everyone who helped and those who tried to help :)