0

I am having a trouble serializing a dataset to json using ServiceStack.Text (from Nuget.org). I am using the latest stable build 4.0.50 and VS 2015. I keep getting

Process is terminated due to StackOverflowException

My code:

using System;
using System.Data;
using System.Data.SqlClient;
using ServiceStack.Text;

namespace TestServiceStackText
{
    class Program
    {
        static void Main(string[] args)
        {
            string ConnectionString = @"Server=MyServer; Database=NORTHWND; User Id=SomeUser; Password=SomePassword;";
            string SqlQuery = @"SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]";

            // Create new dataset instance
            DataSet dataset = new DataSet();

            // Fill it with a little data: 1 table, 1 row
            using (var conn = new SqlConnection())
            {
                using (var da = new SqlDataAdapter())
                {
                    using (da.SelectCommand = conn.CreateCommand())
                    {
                        da.SelectCommand.CommandText = SqlQuery;
                        da.SelectCommand.Connection.ConnectionString = ConnectionString;
                        da.Fill(dataset);
                    }
                }
            }

            // Serialize to json: exception occurs here
            string json = TypeSerializer.SerializeToString<DataSet>(dataset);
            Console.WriteLine("Dataset serialized to json:\n {0}", json); 

            // Deserialize to DataSet
            DataSet ds = TypeSerializer.DeserializeFromString<DataSet>(json);
            Console.WriteLine("Name: {0}, Nr. of Tables: {1}", ds.DataSetName, ds.Tables.Count);
        }
    }
}

Suggestions anybody?

Erik B
  • 3
  • 3
  • 2
    I Suspect that their is a circular dependency in the `DataSet` and servicestack will keep trying to serialize all properties even if it has already serialized them before. – sQuir3l Dec 10 '15 at 10:43

1 Answers1

2

None of ServiceStack's text serializers have explicit support for DataSet's which are a horrible type for serialization.

Micro ORM's like OrmLite ends up being much cleaner and easier to use which maps to clean POCO's that are ideal for serialization, e.g the equivalent code for your above query is:

var customers = Db.Select<Customer>(q => q.Take(1));

var json = customers.ToJson();
var dto = json.FromJson<Customer>();

Or if you don't want to create a Customer type you can use OrmLite's dynamic API's to map to a lose typed List of objects:

var list = Db.Select<List<object>>(
   "SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]");

Or a Dictionary:

var dict = Db.Select<Dictionary<string,object>>(
   "SELECT TOP 1 * FROM [NORTHWND].[dbo].[Customers]");

Checkout the northwind.servicestack.net project for code examples of using OrmLite and AutoQuery to query the Northwind dataset.

In summary, you'll have a lot less issues if you use clean POCOs instead of DataSets which are supported in every serializer, are much smaller and faster than DataSet's, you can also serialize POCO's or loose-typed Dictionary's to CSV with ServiceStack.Text:

var csv = customers.ToCsv();
var csv = dict.ToCsv();
Community
  • 1
  • 1
mythz
  • 141,670
  • 29
  • 246
  • 390
  • All of the above makes good sense, but I chose dataset as my DTO because I need it to be completely generic. In my project the query will vary every time so the DTO must handle that, and be a known type on the receiving end of an WCF client that needs to deserialize it. However, I have noticed that serialize/deserializing datasets is an expensive operation. I am using Newtonsoft.Json currently ,and I am looking for a better DTO and/or faster serializer component than I currently have. – Erik B Dec 11 '15 at 09:39
  • @ErikB That's also what the dynamic API's let you do. Note DataSet's have been deprecated with no plans to add them to CoreCLR. They're a heavy, complicated data structure that's a poor choice for serialization. I'd recommend moving to clean POCO's or generic collections which are both more interoperable, have no deps and are going to cause you less issues in the future. – mythz Dec 11 '15 at 11:40