Search code examples
c#wcfserializationprotobuf-netcommunicationexception

Serialization issue with protobuf and WCF


I am using protobuf to to serialize dataset and send it from WCF service to winfom client.

I am facing two issues here...

  1. DataSet is coming from DB and it contains a column of type system.Object which protobuf is not able to handle and throwing below exception...

    Cannot serialize data column of type 'System.Object'. Only the following column types are supported: Boolean, Byte, Byte[], Char, Char[], DateTime, Decimal, Double, Guid, Int16, Int32, Int64, Single, String."}

Code for serialization of Dataset

using (var ms = new MemoryStream())
                    {
                        if (ReportData.Tables.Count > 0)
                        {
                            DataSerializer.Serialize(ms, ReportData);
                           }
                    }

How can I force protobuf to to serialize system.Object data type column. I tried to convert this system.Object type column to string then serialize... in this case everything works fine but it is time consuming process as I need to clone the table and import all the rows (my dataset contains millions of rows).

 DataTable dtCloned = ReportData.Tables[0].Clone();
                    foreach (DataColumn column in dtCloned.Columns)
                    {
                        if (column.DataType == typeof(System.Object))
                            objectColumns.Add(column);
                    }
                    if (objectColumns.Count > 0)
                    {
                        foreach (DataColumn column in objectColumns)
                        {
                            column.DataType = typeof(System.String);
                        }
                    }
                    try
                    {
                        foreach (DataRow row in ReportData.Tables[0].Rows)
                        {
                            dtCloned.ImportRow(row);
                        }
                    }
                    catch (Exception ex)
                    {

                    }

This is the sample code i wrote for the same. DB type for this System.Object is SQL_Variant and we cannot change this as this is legecy SP and the column contains different type of data (decimal, int varchar).

Is ther any better way to achieve the same.

  1. When this serialization failed and throw error... on client side I am getting communication Exception which contains no clue what went wrong.The only thing it says is...

    "The underlying secure session has faulted before the reliable session fully completed. The reliable session was faulted."

I have tried setting below thing in WCF service side but no use...

 <serviceDebug includeExceptionDetailInFaults="true" />

also tried with passing FaultException... no luck

How can I pass the correct exception and info from WCF service to my client.

Thanks in advance.


Solution

  • Ultimately, protobuf-net has some pretty fundamental objections to object. It also doesn't ship with pre-built support for DataTable. Frankly I'd challenge the suitability of using DataTable as an exchange type, preferring a well-typed DTO.

    If you must use DataTable for some reason, I wonder whether your best bet is to serialize that separately making sure to use the binary format (see RemotingFormat) and writing to a MemoryStream, then fetch out the bytes (ToArray in this case) and just hand WCF the byte[]. Reverse at the other end.