CsvServiceClient exception when response DTO contains a dictionary

I’m receiving an exception when using the CsvServiceClient but not the Json or Xml clients. The issue appears to be because I have a dictionary in my response DTO.

An exception of type 'System.IndexOutOfRangeException' occurred in ServiceStack.Client.dll but was not handled in user code

Additional information: Index was outside the bounds of the array.

My service

namespace ImplementSoap.ServiceInterface
{
    public class MyServices : Service
    {
        public object Any(Hello request)
        {
            return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) };
        }
    }
}

My DTOs

namespace ImplementSoap.ServiceModel
{
    [DataContract]
    [Route("/hello/{Name}")]
    public class Hello : IReturn<HelloResponse>
    {
        [DataMember]
        public string Name { get; set; }
    }

    [DataContract]
    public class HelloResponse
    {
        [DataMember]
        public string Result { get; set; }
        [DataMember]
        List<ComplexFlatObject> { get; set; }
        [DataMember]
        public Dictionary<string, string> CustomDict { get; set; }
    }
}

My test

namespace ImplementSoap.Tests
{
    [TestFixture]
    public class MyServiceTests
    {
        [Test]
        public void X_X_X()
        {
            using (var client = new CsvServiceClient("http://localhost:8088"))
            {
                Hello request = new Hello { Name = "Bob" };
                var response = client.Get(request);
            }
        }
    }
}

You shouldn’t be using the CsvServiceClient with a non-tabular Response. e.g. you can use CSV with a List<T> or a Response DTO containing a List<T>.

What are you expecting the CSV format for that response to be serialized to?

Now that you pointed it out using the CsvServiceClient on non-tabular responses doesn’t make sense. However, I’m seeing cases where it does work. I updated my DTO example to include a List property.

Attempting to use the CSV client like the JSON or XML fails

var response = _csvClient.Get(dtoRequest);

If I specify the type as the list type in my DTO it works

var response = _csvClient.Get<List<ComplexFlatObject>>(dtoRequest);

The above meets my needs (while misusing the CsvServiceClient I understand) but I can’t do something similar when it’s just a ComplexFlatObject instead of a List<>

Both don’t work

var response = _csvClient.Get(dtoRequest);
var response = _csvClient.Get<ComplexFlatObject>(dtoRequest);

Any thoughts on why that doesn’t work. Having written this up I’m leaning towards disabling the CSV format and if customer really needs it then I would create specific DTOs for CSV.

CSV format isn’t a general purpose serialisation format, it should only be used for tabular responses, I.e if you’re returning a List or your Response DTO contains a List property which it serializes instead of the entire Response DTO.

Also it’s not typical to use the CsvServiceClient as the CSV Response is normally consumed directly in Apps that can load CSVs, e.g a spreadsheet or an RDBMS.