asp.net-coreservicestackservicestack-text

ServiceStack - Year, Month, and Day parameters describe an un-representable DateTime even using JsConfig


I have looked at multiple resources online, but whatever I try just doesn't seem to work. What am I doing wrong?

using directives

using ServiceStack;
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

Code

JsConfig<DateTime>.DeSerializeFn = str => DateTime.ParseExact(str, "dd/MM/yyyy hh:mm", CultureInfo.InvariantCulture);

using (var fs = File.Open(@"C:\temp\data.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    var data = CsvSerializer.DeserializeFromStream<List<Class>>(fs);
}

Also tried

JsConfig<DateTime>.DeSerializeFn = str => DateTime.ParseExact(str, "dd/MM/yyyy hh:mm", CultureInfo.InvariantCulture);
var list = File.ReadAllText(@"C:\temp\data.csv").FromCsv<List<Class>>();

And what is in the csv file?

StartDate, FirstRedemptionDate, FirstSubscriptionDate

01/08/2014 00:00, 31/08/2014 00:00, 01/08/2014 00:00

30/09/2014 00:00, 01/08/2015 00:00, 30/09/2013 00:00


Solution

  • The issue is because your CSV has both , delimiters and space delimiters, when using , delimiters CSV is whitespace sensitive, e.g. your Headers should instead be:

    StartDate,FirstRedemptionDate,FirstSubscriptionDate
    

    As currently the header value of 'FirstRedemptionDate' is ' FirstRedemptionDate'.

    I've made a change so headers are auto-trimmed in this commit which allows your custom DateTime deserializer to be matched against headers with leading/trailing spaces which is available from the latest v5.7.1 that's now on MyGet.

    Because you've also got leading whitespace in your date values you will also need to trim your value before parsing, e.g:

    JsConfig<DateTime>.DeSerializeFn = str => 
        DateTime.ParseExact(str.Trim(), "dd/MM/yyyy hh:mm", CultureInfo.InvariantCulture);
    

    Which should now parse correctly using the latest v5.7.1 of ServiceStack.Text on MyGet.