2 Replies Latest reply: Feb 4, 2013 8:57 AM by 968966 RSS

    DataSet serialization issue when using netTcpBinding in WCF

    bootstrap
      Hi everyone,
      My database is Oracle 11G and i am developing a .NET WCF application with TCP transport protocol i.e., netTcpBinding.
      I found an issue please anyone help me .

      My service method returns DataSet (xsd) . This service method is working fine when i am using basicHttpBinding but this service method is returniong null when i am using netTcpBinding.

      One more thing that when i use this xsd DataSet and create tables using SqlServer database then there is no problem even when using netTcpBinding.

      So, i concluded that using netTcpBinding with DataSet populated using Oracle tables causing problem.
      My development machine is Win 7 Enterprise 64 bit and i am using ODP as data provider.
      Can anyone please help.
      From Microsoft community i did'nt got any resonable help despite lots of hard work there.
        • 1. Re: DataSet serialization issue when using netTcpBinding in WCF
          636190
          Howdy,
          Just a couple things to look at.

          By any chance are there UDT's within the datatable(s)?
          Do the datatables have Oracle Type or Microsoft Type columns?
          If you are attempting to serialize Oracle types with the WCF serializers this may be the issue.

          A few years back there were "issues" with the MS serializers used within WCF so I avoided it all together.
          I ended up serializing my Datasets myself and sending byte[]. All works very well.
                  public static DataSet ExtractSerializedDataSet(byte[] ba)
                  {
                      MemoryStream ms = new MemoryStream(ba);
                      BinaryFormatter bf = new BinaryFormatter();
                      object o = bf.Deserialize(ms);
                      DataSet ads = o as DataSet;
                      if (ads != null && ads.Tables.Count > 0)
                          return ads;
                      else
                          return null;
                  }
          
                  public static byte[] SerializeDataSet(ref DataSet _ds)
                  {
                      _ds.RemotingFormat = SerializationFormat.Binary;
                      _ds.SchemaSerializationMode = SchemaSerializationMode.IncludeSchema;
                      MemoryStream ms = new MemoryStream();
                      BinaryFormatter bf = new BinaryFormatter();
                      bf.Serialize(ms, _ds);
                      if (ms.Length > 0)
                          return ms.ToArray();
                      else
                          return null;
                  }
          and my service/operations contract looks like this:
             [ServiceContract(Namespace = "WCF.BYTE.SERVICES",
                              CallbackContract = typeof(IByteSrvcCallback),
                              SessionMode = SessionMode.Required)]
              public interface IByteSrvcWCallback
              {
                  //Control commands and data
                  [OperationContract(IsOneWay = true)]
                  void SimpleControlPacket(string originatorDQGuid, byte[] baIn);
                  //For the server from the client(s)
                  [OperationContract(IsOneWay = true)]
                  void SuspenseQDataPacket(string originatorDQGuid, byte[] data);
          
                  [OperationContract]
                  string Subscribe(string guidSuffix);
                  [OperationContract(IsOneWay = true)]
                  void UnSubscribe(string clientId);
          
                  [OperationContract(IsOneWay = true)]
                  void NoOpButKeepAlive();
              }
              public interface IByteSrvcCallback
              {
                  //For the clients
                  [OperationContract(IsOneWay = true)]
                  void ProcessedDQDataPacket(string for_originatorDQGuid, byte[] baOut);
                  //For the clients
                  [OperationContract(IsOneWay = true)]
                  void ProcessedSimpleControlPacket(string for_originatorDQGuid, byte[] baOut);
              }
          r,
          dennis
          • 2. Re: DataSet serialization issue when using netTcpBinding in WCF
            968966
            Serializing dataset is not what's recommended with web services. It is not a good design, you face serialization issues, and many more...
            Consider using a class which maps/represent a Datarow.
            Below an example on how to achieve that.

            //you run a proc or select then receive a dsOut dataset
            var records = new List<MyClassRepresentingARow>();
            records.AddRange(from DataRow row in dsOut.Tables[0].Rows
                                     select MyServiceDataMapper.PopulateMyClassFromRow(row));


            //this is the class mapping the datarow
            [DataContract]
            public class MyClassRepresentingARow
            {
            [DataMember]
            public long Id { get; set; }

            [DataMember]
            public int TypeId { get; set; }
            }

            // this is the class that creates instances based on rows
            public static MyClassRepresentingARow PopulateMyClassFromRow(DataRow row)
            {
                 var data = new MyClassRepresentingARow();
                 if (row != null)
                 {
                      data.Id = row.NullSafeLong("ID");
                      data.TypeId = (int)row.NullSafeLong("TYPEID");
            }
            return data;
            }