Returning DataTables in WCF/.NET

Solution 1:

For anyone having similar problems, I have solved my issue. It was several-fold.

  • As Darren suggested and Paul backed up, the Max..Size properties in the configuration needed to be enlarged. The SvcTraceViewer utility helped in determining this, but it still does not always give the most helpful error messages.
  • It also appears that when the Service Reference is updated on the client side, the configuration will sometimes not update properly (e.g. Changing config values on the server will not always properly update on the client. I had to go in and change the Max..Size properties multiple times on both the client and server sides in the course of my debugging)
  • For a DataTable to be serializable, it needs to be given a name. The default constructor does not give the table a name, so:

    return new DataTable();
    

    will not be serializable, while:

    return new DataTable("someName");
    

    will name the table whatever is passed as the parameter.

    Note that a table can be given a name at any time by assigning a string to the TableName property of the DataTable.

    var table = new DataTable();
    table.TableName = "someName";
    

Hopefully that will help someone.

Solution 2:

The best way to diagnose these kinds of WCF errors (the ones that really don't tell you much) is to enable tracing. In your web.config file, add the following:

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" 
              switchValue="Information" 
              propagateActivity="true">
        <listeners>
          <add name="ServiceModelTraceListener" 
               type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
               initializeData="wcf-traces.svclog"/>
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

You can then open the resulting file in the SvcTraceViewer.exe utility which comes in the .NET Framework SDK (or with Visual Studio). On my machine, it can be found at %PROGRAMFILES%\Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe.

Just look for an error message (in bold red) and that will tell you specifically what your problem is.

Solution 3:

I added the Datable to a data set and returned the table like so...

DataTable result = new DataTable("result");

//linq to populate the table

Dataset ds = new DataSet();
ds.Tables.Add(result);
return ds.Tables[0];

Hope it helps :)