首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将CsvHelper自定义转换器应用于特定的类映射字段

将CsvHelper自定义转换器应用于特定的类映射字段
EN

Stack Overflow用户
提问于 2021-04-14 07:57:54
回答 1查看 2.2K关注 0票数 2

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

在NextReviewDate映射字段上使用自定义转换器的类Map代码段:

代码语言:javascript
运行
复制
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);
    }
}

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

代码语言:javascript
运行
复制
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;
    }
}   

我如何注册类地图和编写记录的代码片段:

代码语言:javascript
运行
复制
csv.Configuration.RegisterClassMap<MyCustomClassMap>();

csv.WriteRecords(results);

为了排除故障,我在DateTimeStringConverter中添加了一个抛出异常,它似乎从未被调用过。我漏了一块吗?现在,CSV正在生成并包含原始的NextReviewDate映射字段值,而无需调用自定义转换器。

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

代码语言:javascript
运行
复制
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;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-14 09:32:58

CSV助手26.1.0

首先,StringConverter只提供了一种覆盖object ConvertFromString(..)的方法。

对字符串的会话不需要任何处理,因为它应该是一个string

在这里,我想您的类型是DateTime,并且您得到了多个Exotique格式。如果只有一种格式,则可以更改该类型的默认格式。

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

代码语言:javascript
运行
复制
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

具有可自定义的格式、区域性和样式。

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
using (var writer = new StringWriter())
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture, true))
{
    csvWriter.Context.RegisterClassMap<TestMap>();
    csvWriter.WriteRecords(datas);
    csvWriter.Flush();
    csvTextOuput = writer.ToString();
}

结果:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
using (var reader = new StringReader(csvTextOuput))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture, true))
{
    csvReader.Context.RegisterClassMap<TestMap>();
    ObjectFromCSV = csvReader.GetRecords<Test>().ToArray();
}

结果:

代码语言:javascript
运行
复制
[
   {
   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(读者,CultureInfo.InvariantCulture,真)~ =>

同质日期时间格式访问所有属性。

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

注:旧版本的TypeConverterFactoryTypeConverterCache

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67087699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档