1
votes

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.

1
Can I check: what is DataSerializer here? Protobuf-net has never shipped with DataTable serialization in the core library, so: what is that, exactly? Is that the demo custom serialization code? - Marc Gravell
We are using Assembly: protobuf-net-data, Version=2.0.6.640, Culture=neutral, PublicKeyToken=3a92fdc8f425ccde for the same. It ships with protobuf. - Abhash786
"It ships with protobuf" - no, it doesn't. I'm the author of protobuf-net; protobuf-net-data is a completely separate and independent tool by another developer that uses protobuf-net, but which has no affiliation or association with protobuf-net. Compare the "Owners" field here and here - Marc Gravell
yes... protobuf-net-data is separate dll... which support DataSet/DataTable serialization. Does protoBuf has any way to serialize dataTable which contains System.Object type - Abhash786
not really; I expanded on this in my answer and the comment on my answer; it just doesn't like object (for good reasons) very much. It can be forced, but a: I don't recommend it, and b: I doubt you'd be able to combine that with the DataTable support added via this other library - Marc Gravell

1 Answers

1
votes

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.