将 CsvHelper 自定义转换器应用于特定的类映射字段 CSV 助手 26.1.0CSV 助手 7所有属性均采用同类日期时间格式

如何解决将 CsvHelper 自定义转换器应用于特定的类映射字段 CSV 助手 26.1.0CSV 助手 7所有属性均采用同类日期时间格式

运行 CSVHelper 7.0.0 并尝试添加可应用于特定类映射字段的自定义字符串转换器(不想全局应用于字符串类型的所有字段)。下面是关于我目前如何设置类映射、自定义转换器和 csv 编写器调用设置的片段。

在 NextReviewDate 地图字段上使用自定义转换器的类地图代码片段:

public sealed class MyCustomClassMap : ClassMap<MyCustomClass>
{
    public MyCustomClassMap()
    {
        Map(m => m.ContentId).Index(0);
        Map(m => m.Name).Index(1);
        Map(m => m.ContentOwner).Index(2);
        Map(m => m.ContentOwnerName).Index(3);
        Map(m => m.copyrightOwner).Index(4);
        Map(m => m.copyrightOwnerName).Index(5);
        Map(m => m.NextReviewDate).Index(6).TypeConverter<DateTimeStringConverter>();
        Map(m => m.ContentStatus).Index(7);
        Map(m => m.UsageRights).Index(8);
        Map(m => m.SchemaName).Index(9);
    }
}

自定义字符串转换代码片段:

public class DateTimeStringConverter : StringConverter
{
    public override object ConvertFromString(string text,IReaderRow row,MemberMapData memberMapData)
    {
        string formattedDateString = string.Empty;

        if (DateTime.TryParse(text,out DateTime dateobj))
        {
            formattedDateString = dateobj.ToString("MM-dd-yyyy");
        }

        //throw new Exception("DateTimeStringConverter value: " + formattedDateString);

        return formattedDateString;
    }
}   

我如何注册我的类映射和写入记录的代码片段:

csv.Configuration.RegisterClassMap<MyCustomClassMap>();

csv.WriteRecords(results);

为了排除故障,我在 DateTimeStringConverter 中添加一个 throw 异常,并且它似乎永远不会被调用。我缺一块吗?现在 CSV 正在生成并包含原始 NextReviewDate 映射字段值,而无需调用自定义转换器。

编辑:基于@Self 反馈将自定义字符串转换器更改为以下已解决问题:

public class DateTimeStringConverter : DefaultTypeConverter
{
    public override string ConvertToString(object value,IWriterRow row,MemberMapData memberMapData)
    {
        string strVal = (string)value;

        if (DateTime.TryParse(strVal,out DateTime dateobj))
        {
            strVal = dateobj.ToString("MM-dd-yyyy");
        }

        return strVal;
    }
}

解决方法

CSV 助手 26.1.0

第一个 StringConverter 仅提供一种覆盖 object ConvertFromString(..) 的方法。
对字符串的转换没有任何处理,因为它假设是一个 string

这里我假设您的 Type 是 DateTime 并且您以 multiple Exotique 格式获得它。如果您只有一种格式,您可以更改该类型的默认格式。

一个简单的演示类及其映射:

public class Test
{
    public int Id { get; set; }
    public DateTime DateTime { get; set; }
    public DateTime Date { get; set; }
    public DateTime Time { get; set; }
}
public sealed class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        AutoMap(CultureInfo.InvariantCulture);
        Map(x => x.Date).TypeConverter(new DateStringConverter("MM - dd - yyyy"));
        Map(x => x.Time).TypeConverter(new DateStringConverter("mm # hh # ss"));
    }
}

我使用了一个继承自 ITypeConverter 的转换器,以便同时拥有 ConvertFromStringConvertToString
具有可自定义的格式、文化和风格。

public class DateStringConverter : ITypeConverter
{
    private readonly string _dateFormat;
    private readonly CultureInfo _CultureInfo;
    private readonly DateTimeStyles _DateTimeStyles;

    public DateStringConverter(string dateFormat) :
    this(dateFormat,CultureInfo.InvariantCulture,DateTimeStyles.None)
    { }

    public DateStringConverter(string dateFormat,CultureInfo cultureInfo,DateTimeStyles dateTimeStyles)
    {
        _dateFormat = dateFormat;
        _CultureInfo = cultureInfo;
        _DateTimeStyles = dateTimeStyles;
    }

    public object ConvertFromString(string text,IReaderRow row,MemberMapData memberMapData)
    {
        string formattedDateString = string.Empty;
        if (DateTime.TryParseExact(text,_dateFormat,_CultureInfo,_DateTimeStyles,out DateTime dateObj))
        {
            return dateObj;
        }
        return null;
    }
    public string ConvertToString(object value,IWriterRow row,MemberMapData memberMapData)
    {
        if (value == null) return string.Empty;

        if (DateTime.TryParse(value.ToString(),out DateTime dt))
            return dt.ToString(_dateFormat);
        else
            return string.Empty;
    }
}

编写 CSV:

using (var writer = new StringWriter())
using (var csvWriter = new CsvWriter(writer,true))
{
    csvWriter.Context.RegisterClassMap<TestMap>();
    csvWriter.WriteRecords(datas);
    csvWriter.Flush();
    csvTextOuput = writer.ToString();
}

结果:

Id,DateTime,Date,Time
1,04/14/2021 09:18:02,04 - 14 - 2021,18 # 09 # 02
2,04/15/2021 09:18:02,04 - 15 - 2021,18 # 09 # 02
3,04/16/2021 12:18:02,04 - 16 - 2021,18 # 12 # 02

读取 CSV:

using (var reader = new StringReader(csvTextOuput))
using (var csvReader = new CsvReader(reader,true))
{
    csvReader.Context.RegisterClassMap<TestMap>();
    ObjectFromCSV = csvReader.GetRecords<Test>().ToArray();
}

结果:

[
   {
   Date      : 04/14/2021
   DateTime  : 04/14/2021
   Id        : 1
   Time      : 04/14/2021
   },{
   Date      : 04/15/2021
   DateTime  : 04/15/2021
   Id        : 2
   Time      : 04/14/2021
   },{
   Date      : 04/16/2021
   DateTime  : 04/16/2021
   Id        : 3
   Time      : 04/14/2021
   }
]

现场演示https://dotnetfiddle.net/EMdhtn


CSV 助手 7

https://dotnetfiddle.net/5DgwxY

唯一的修改应该是读写器中没有文化。而 RegisterClassMapConfiguration 移动到 Context

  • ~new CsvReader(reader,true))~ => new CsvReader(reader))
  • ~csvWriter.Context.RegisterClassMap()~ => csvWriter.Configuration.RegisterClassMap();

所有属性均采用同类日期时间格式。

如果您在任何地方都拥有相同的格式,那么建议的解决方案:

注意:TypeConverterFactory 或旧版本的 TypeConverterCache

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?