尝试实现CSVHelper的类型转换器没有效果

发布于 2025-01-28 00:50:20 字数 1584 浏览 5 评论 0原文

我正在尝试全局注册一个CSVHELPER类型转换器,该转换器处理值nullDECIMAL?,但是当我进行注册时,忽略了注册,并且未调用转换器。不知道还有什么要做。

我的转换器:

public class NullDecimalConverter : DecimalConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData mapData)
    {
        if (text == "NULL") return null;
        return base.ConvertFromString(text, row, mapData);
    }
}

我的类和映射如下:

public class Model
{
    public decimal? Score{ get; set; }      
}

public class ScoreMapping : ClassMap<Model>
{
    public ScoreMapping()
    {
        Map(m => m.Score).Name("sub_score");
    }
}

要设置它,

csvReader.Context.RegisterClassMap<ScoreMapping>();
csvReader.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
var records = csvReader.GetRecords<Model>().ToList();

但库不这样做,它是

CsvHelper.TypeConversion.TypeConverterException : The conversion cannot be performed.
    Text: 'NULL'
    MemberType: System.Nullable`1[[System.Decimal, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
    TypeConverter: 'CsvHelper.TypeConversion.NullableConverter'

emo fiddle 在这里< /a>。


作为解决方法,似乎我可以在每种类型上添加TypeConverter,但这很笨拙,有没有适当的方法在全球注册类型的转换器?

Map(m => m.Score).Name("sub_score").TypeConverter<NullDecimalConverter>();

I am trying to globally register a CsvHelper type converter that handles the value NULL for a decimal?, but when I do the registration is ignored and the converter is not invoked. Not sure what else to do.

My converter:

public class NullDecimalConverter : DecimalConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData mapData)
    {
        if (text == "NULL") return null;
        return base.ConvertFromString(text, row, mapData);
    }
}

My class and mapping are as follows:

public class Model
{
    public decimal? Score{ get; set; }      
}

public class ScoreMapping : ClassMap<Model>
{
    public ScoreMapping()
    {
        Map(m => m.Score).Name("sub_score");
    }
}

And to set it up

csvReader.Context.RegisterClassMap<ScoreMapping>();
csvReader.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
var records = csvReader.GetRecords<Model>().ToList();

But the library doesn't do it

CsvHelper.TypeConversion.TypeConverterException : The conversion cannot be performed.
    Text: 'NULL'
    MemberType: System.Nullable`1[[System.Decimal, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
    TypeConverter: 'CsvHelper.TypeConversion.NullableConverter'

Demo fiddle here.


As a workaround, it seems I can add the TypeConverter on each type, but this is clunky, is there a proper way to register the type converter globally?

Map(m => m.Score).Name("sub_score").TypeConverter<NullDecimalConverter>();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2025-02-04 00:50:20

这里的问题是执行顺序...
AddConverter必须在registerClassMap之前调用,否则将不会注册转换器。

我认为我应该将其作为错误提出,因为依靠订单可能是要避免的,尤其是在很容易被忽略的库中。

    // fails because class map is registered first
    csv.Context.RegisterClassMap<ScoreMapping>();
    csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());

    // works because TypeConverter is added first
    csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
    csv.Context.RegisterClassMap<ScoreMapping>();

The issue here was order of execution...
AddConverter must be called before RegisterClassMap else the converter will not be registered.

I reckon I should raise this as a bug because relying on order is probably something to avoid, especially in a library where this could easily be overlooked.

    // fails because class map is registered first
    csv.Context.RegisterClassMap<ScoreMapping>();
    csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());

    // works because TypeConverter is added first
    csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
    csv.Context.RegisterClassMap<ScoreMapping>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文