1

I am sending a CSV and de-serializing it.

 List<CompanyService> responseX;
            using (var reader = new StreamReader(files[0].InputStream))
            {
                // convert stream to string
                string text = reader.ReadToEnd();
                List<InsertCompany> deserializeFromString = ServiceStack.Text.CsvSerializer.DeserializeFromString<List<InsertCompany>>(text);
                responseX = Gateway.SendAll<CompanyService>(deserializeFromString);
            }


 /// <summary>
        /// To insert the company
        /// </summary>
        /// <returns></returns>
        public long Post(InsertCompany request)
        {
            var company = request.ConvertTo<Company>();
            company.AuditId = UserAuth.Id;
            var result = Db.Insert<Company>(company, selectIdentity: true);

            //History
            CreateCompanyHistory(result, "INSERT", UserAuth.Id);

            //See the SQL that was generated
            //var lastSql = Db.GetLastSql();
            return result;
        }

When I call Sendall it calls the CompanyService and proesses all the List then sends back an error. but the records get saved in the database. error= System.Runtime.Serialization.SerializationException: 'Type definitions should start with a '{', expecting serialized type 'CompanyService', got string starting with: 71'

On a side note, I cannot find any documentation for the ServiceStack.Text.CsvSerializer.DeserializeFromString

Edit--

My CSV for Clarity

CompanyName,ParentCompanyId,City,Country,Email,Phone,Address1,Address2,Latitude,Longitude
Sub Company 8A,8,,,a@c.n,,dfg,,0,0
Sub Company 8B,8,,,W@RF.COM,7777,f,,0,0
Sub Company 8C,8,,,a@c.com,7777,d,,0,0
Sub Company 8D,8,,,abc@gmail.com,7777,2,,0,0
Sub Company 8E,8,,,abc@gmail.com,7777,2,,0,0
Sub Company 8F,8,,,abc@gmail.com,7777,2,,0,0

-edit 2

These were the first APIs i wrote using ST. I forgot to modify them to use a correct return type. This is what I have been using and switching to it resolved the error.

public class ResponseList : IResponseItemList
{
    public List<dynamic> Result { get; set; }
}

public interface IResponseItemList
{
    List<dynamic> Result { get; set; }
}

public class Response : IResponseItem
{
    public dynamic Result { get; set; }
}

public interface IResponseItem
{
    dynamic Result { get; set; }
}
Steve Coleman
  • 1,987
  • 2
  • 17
  • 28

1 Answers1

1

The error indicates that the CSV is not in the format CsvSerializer expects, e.g. you would get this error when trying to deserialize JSON in CSV.

The only text that the CsvSerializer.Deserialize* APIs should be deserializing is CSV that was originally serialized with CsvSerializer. It should be able to deserialize simple generic CSV files, but the moment you have any complex Types (which CSV doesn't support) it expects the opinionated output generated by CsvSerializer.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • The serializer seems to be working fine. It's erroring after it calls SendAll and after all the loops happen to call the Insert records. It's failing on the return. I added my csv if it helps. – Steve Coleman Sep 03 '19 at 17:00
  • @SteveColeman ok your Services [should not return value types only reference Types](https://docs.servicestack.net/service-return-types#services-should-only-return-reference-types). The return Type should be whatever `IReturn` type your `InsertCompany` Request DTO is implementing which should be a reference type like a Response DTO, or can be a `string`. If you want to return `void` have your Service implement `IReturnVoid` that you can call from your gateway with `PublishAll()`. – mythz Sep 03 '19 at 17:05
  • I posted what I used to resolve it. Seems to work fine. Do you see any issue with dynamic types? – Steve Coleman Sep 03 '19 at 21:46
  • @SteveColeman Yes it will fail in a lot of serializers and different languages and unknown types like `object` has [imposed security restrictions](https://github.com/ServiceStack/ServiceStack.Text#late-bound-object-and-interface-runtime-types). Use a string if you want to hold an arbitrary types, or my recommendation is to [use explicit Request DTOs](https://docs.servicestack.net/why-remote-services-use-dtos) as it forms part of your Service Contract which will let you [version Services gracefully](https://stackoverflow.com/a/12413091/85785) without breaking existing clients. – mythz Sep 03 '19 at 21:53
  • @SteveColeman You can also use a Generic Response Types, `dynamic` is likely going to cause you runtime interoperability issues in future. – mythz Sep 03 '19 at 21:57
  • Thanks Demis, Appreciate the responses. – Steve Coleman Sep 03 '19 at 22:09