CsvHelper set default custom TypeConverter

前端 未结 3 1439
离开以前
离开以前 2020-12-21 04:05

With CsvHelper, when I want a custom parser (for example, I want a MyBooleanConverter with the input string is \"f\" will be false, \"t\" will

相关标签:
3条回答
  • 2020-12-21 04:58

    The CsvHelper library exposes a static TypeConverterFactory. You can simply remove the default Boolean converter and add your custom converter to replace it.

    TypeConverterFactory.RemoveConverter<bool>();
    TypeConverterFactory.AddConverter<bool>(new MyBooleanConverter());
    
    0 讨论(0)
  • 2020-12-21 04:58

    It's also possible to have CsvHelper generate your ClassMap, at which point you can customize its handling for your members. I found this useful for getting things done in my little hobby project.

    var csv = new CsvReader(streamReader, false);
    var classMap = csv.Configuration.AutoMap<Row>(); // ClassMap creation
    
    // My price data has dollar signs so those need to be stripped out before parsing to a decimal
    classMap.Map(row => row.Price).ConvertUsing(row => decimal.Parse(row.GetField("Price").Replace("$", "")));
    
    // CsvHelper doesn't support URIs so that requires help as well
    classMap.Map(row => row.Source).ConvertUsing(row => new Uri(row.GetField("Source")));
    
    var prices = csv.GetRecords<Row>();
    
    
    
    // my DTO
    class Row
    {
        public decimal Price { get; set; }
        public string ManufacturerSku { get; set; }
        public string Manufacturer { get; set; }
        public Uri Source { get; set; }
        public DateTimeOffset Extraction_Time { get; set; }
    }
    
    0 讨论(0)
  • 2020-12-21 05:08

    Just adding my code snippet to the following post to help understand the Type Converters built into CsvHelper. I needed to handle dates in the following format "yyyyMMdd" and it seemed to do the trick writing back and forth to CSV without the .net DateTime Parse error: "String was not recognized as a valid DateTime."

    using (TextWriter writer = new StreamWriter(csvLocaitonAndName))
            {
                var csvUpdate = new CsvWriter(writer);
                csvUpdate.Configuration.TypeConverterCache.AddConverter<DateTime?>(new DateConverter("yyyyMMdd"));
                csvUpdate.Configuration.HasHeaderRecord = false;
                csvUpdate.WriteRecords(list);
            }
    
    public class DateConverter : ITypeConverter
        {
            private readonly string _dateFormat;
    
            public DateConverter(string dateFormat)
            {
                _dateFormat = dateFormat;
            }
    
            public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
            {
                if (!string.IsNullOrEmpty(text))
                {
                    DateTime dt;
                    DateTime.TryParseExact(text, _dateFormat,
                                           CultureInfo.InvariantCulture,
                                           DateTimeStyles.None,
                                           out dt);
                    if (IsValidSqlDateTime(dt))
                    {
                        return dt;
                    }
    
                }
    
                return null;
            }
            public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
            {
                return ObjectToDateString(value, _dateFormat);
            }
    
            public string ObjectToDateString(object o, string dateFormat)
            {
                if (o == null) return string.Empty;
    
                DateTime dt;
                if (DateTime.TryParse(o.ToString(), out dt))
                    return dt.ToString(dateFormat);
                else
                    return string.Empty; 
            }
            public bool IsValidSqlDateTime(DateTime? dateTime)
            {
                if (dateTime == null) return true;
    
                DateTime minValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MinValue.ToString());
                DateTime maxValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());
    
                if (minValue > dateTime.Value || maxValue < dateTime.Value)
                    return false;
    
                return true;
            }
    
    0 讨论(0)
提交回复
热议问题