Thursday, July 26, 2012

DataTable & WCF Service

In this post we will be discussing a minor issue with the serialization of DataTable in WCF. We, then would present its solution. The issue is that we cannot send a DataTable object across the wire for which TableName property is not set. If we do try to send it, it throws exception. The post would just have an example to show the issue and its solution.

There are a lot of material you can find, not recommending DataSet and DataTable on WCF boundaries. But you might run into situations where some architectural design decisions are horribly taken and you cannot change them. This case would be one of them. Or this might be a client requirement which needs data in this format.

Let's create a WCF Library project DataTableWCFApp.Service. We can update the service contract as follows:

We can use the following as the implementation of the ServiceContract interface presented above. This is just creating a untyped DataTable, filling it with a single row and returning it.

We wouldn't be able to test it using WCF Test Client because of non-primitive DataTable type which it cannot deserialize.

So let's create a simple MVVM Light WPF project to test it. Here we are creating a project with name DataTableWCFApp as follows:

After adding the service reference for the DataTable Service, we need to update the view and view model for showing the DataTable returned from the service. Let's update MainWindow as follows:

So the view expects a collection MyData in its DataContext. The collection is expected to be available at the time of loading the view, hence OneTime mode for Binding. Let's update the view model as follows:

Before running it, we need to find a way to host the WCF Service. Luckily Visual Studio makes it easier for us. Just check the following option is checked for your WCF project. This would host the WCF Service when another project in the solution is being debugged. If we set the WCF Service project as the start up project then this would host it in WCF Service Host, additionally, this would launch WCF Test Client for the service.

Now set the WPF Project as the Startup Project and run it. We get the following CommunicationException with no details about what actually happened or how to fix it.

In order to find the actual cause, let's take some help from WCF Service Trace Viewer. We need to add the following configuration in our WCF Service project's app.config file.

Now we can run it again. We would again get the same exception but the traces should be recorded in the location for the trace file as mentioned in the above configuration. Let's try opening the file using Microsoft Service Trace Viewer. We need to install Windows SDK for this tool. It shows the actual cause of the problem.
The error message is descriptive enough. We are just missing to set the TableName of the DataTable. The DataTable cannot be serialized without setting it. Let's update the Service to do the same as follows:

Now we run the project again. Now the service returns the response without any issue. The DataTable is used by the view to display it in a DataGrid. For an untyped DataTable, this would be the most suitable control as this can analyze data and create columns based on the data in the DataTable. Other control, e.g. ListBox would show DataRowView for each entry in the DataTable.


No comments: