Data Transfer using WCF

So forgetting OData for a minute (not hard to do), I was thinking about how to transfer SDO classes to and from a WCF service.  All of the WCF projects I have worked on have been POCOs with the appropriate WCF attributes from System.ServiceModel and System.Runtime.Serialization.  I never thought about putting an ADO.NET recordset as a return value from a WCF method.  I also wondered about putting the recordset as a parameter to a WCF method.  I assume it is possible, I was curious about how much effort it would take.  I Binged on Google (or was it Googled on Bing) and these was nothing that jumped out.

I fired up a typical WCF project and then added a consuming console app to the solution.  I then wrote an interface that returns a dataTable like so:

[ServiceContract]
public interface IDataFactory
{
    [OperationContract]
    DataTable GetDataTable();
}
public class DataFactory : IDataFactory
{
    public DataTable GetDataTable()
    {
        throw new NotImplementedException();
    }
}

I then hit F6 and sure enough it compiled.  I then changed the implementation to this

public DataTable GetDataTable()
{
    DataTable dataTable = new DataTable();
    dataTable.TableName = "Customers";
    dataTable.Columns.Add("CustomerId");
    dataTable.Columns.Add("CustomerName");

    DataRow row1 = dataTable.NewRow();
    row1[0] = 1;
    row1[1] = "Customer #1";
    dataTable.Rows.Add(row1);
    DataRow row2 = dataTable.NewRow();
    row2[0] = 2;
    row2[1] = "Customer #2";
    dataTable.Rows.Add(row2);

    return dataTable;

}

and I am still compiling.  So then I went to the client and added a reference and it worked:

image

I then fired up the client like so:

static void Main(string[] args)
{
    Console.WriteLine("Starting");

    DataFactoryClient client = new DataFactoryClient();
    DataTable table = client.GetDataTable();

    foreach (DataRow row in table.Rows)
    {
        Console.WriteLine(String.Format("Customer {0} named {1}.",row[0],row[1]));
    }

    Console.WriteLine("Ending");
    Console.ReadKey();
}

And I hit F5:

image

 

Wow.  Microsoft made this stupid simple.

I then though about how to pass in an individual data row. 

[OperationContract]
String InsertDataRow(DataRow row);
public String InsertDataRow(DataRow row)
{
    return String.Format("You entered {0}.", row[0].ToString());
}

And when I hit update reference from my consuming app, I got this:

image

Crud!  I then thought I could just add a serializable data row like so:

[Serializable]
public class SerializableDataRow: DataRow
{
}

And this:

[OperationContract]
String InsertDataRow(SerializableDataRow row);

But no, I get this:

image

So now I have to jump down a rabbit hole and possible violate the Liskov Substitution Principle.  Since I want things to be stupid simple, I gave up with inheritance.  I then found this post.  So either use a datatable (and suffer the overhead) or convert the DataRow into something that can be seialized (like XML, custom classes, etc..)

So I give Microsoft a C on this – somewhat stupid simple, but not entirely…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: