- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用出色的 CsvHelper 库(当前为 v12.2.2)来生成 CSV 文件,并且我正在尝试添加我自己的自定义属性以直接在类中指定特殊格式。
我正在写的记录看起来像这样(尽管集成需要大约 200 个数字字段):
class PayrollRecord {
public int EmployeeID { get; set; }
public decimal RegularPay { get; set; }
public decimal RegularHours { get; set; }
public decimal RegularRate { get; set; }
public decimal OvertimePay { get; set; }
public decimal OvertimeHours { get; set; }
public decimal OvertimeRate { get; set; }
// many many more
}
using CsvHelper;
using CsvHelper.TypeConversion;
// convert decimal to the given number of places, and zeros are
// emitted as blank.
public abstract class MyDecimalConverter : DefaultTypeConverter
{
protected virtual string getFormat() => "";
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
if (value is decimal d)
return (d == 0) ? string.Empty : string.Format(getFormat(), d);
return base.ConvertToString(value, row, memberMapData);
}
}
public class DollarsConverter : MyDecimalConverter
{
protected override string getFormat() => "{0:0.00}"; // 2 decimal places
}
public class HoursConverter : MyDecimalConverter
{
protected override string getFormat() => "{0:0.000}"; // 3 decimal places
}
public class PayRateConverter : MyDecimalConverter
{
protected override string getFormat() => "{0:0.0000}"; // 4 decimal places
}
CsvWriter Writer = new CsvWriter( /* stuff */ );
var classMap = new DefaultClassMap<PayrollRecord>();
classMap.AutoMap();
classMap.Map(m => m.RegularPay).TypeConverter<DollarsConverter>();
classMap.Map(m => m.RegularHours).TypeConverter<HoursConverter>();
classMap.Map(m => m.RegularRate).TypeConverter<PayRateConverter>();
classMap.Map(m => m.OvertimePay).TypeConverter<DollarsConverter>();
classMap.Map(m => m.OvertimeHours).TypeConverter<HoursConverter>();
classMap.Map(m => m.OvertimeRate).TypeConverter<PayRateConverter>();
// many more
Writer.Configuration.RegisterClassMap(classMap);
...
[Format("..")]
注释每个字段属性,但为了获得我正在寻找的零抑制,格式字符串是一个由三部分组成的丑陋东西,看起来非常容易出错并且更改起来非常乏味。
// custom attribute
public enum NumericType { Dollars, Hours, PayRate };
public class DecimalFormatAttribute : System.Attribute
{
public NumericType Type { get; }
public DecimalFormatAttribute(NumericType t) => Type = t;
}
// then later
class PayrollRecord {
[DecimalFormat(NumericType.Dollars)] public decimal RegularPay { get; set; }
[DecimalFormat(NumericType.Hours)] public decimal RegularHours { get; set; }
[DecimalFormat(NumericType.PayRate)] public decimal RegularRate { get; set; }
// etc.
}
var classMap = new DefaultClassMap<PayrollRecord>();
classMap.AutoMap();
foreach (var prop in typeof(PayrollRecord).GetProperties())
{
var myattr = (DecimalFormatAttribute)prop.GetCustomAttribute(typeof(DecimalFormatAttribute));
if (myattr != null)
{
// prop.Name is the base name of the field
// WHAT GOES HERE?
}
}
最佳答案
您可以应用 CsvHelper.Configuration.Attributes.TypeConverterAttribute
而不是您自己的自定义属性。到您的模型以指定适当的转换器:
class PayrollRecord
{
public int EmployeeID { get; set; }
[TypeConverter(typeof(DollarsConverter))]
public decimal RegularPay { get; set; }
[TypeConverter(typeof(HoursConverter))]
public decimal RegularHours { get; set; }
[TypeConverter(typeof(PayRateConverter))]
public decimal RegularRate { get; set; }
[TypeConverter(typeof(DollarsConverter))]
public decimal OvertimePay { get; set; }
[TypeConverter(typeof(HoursConverter))]
public decimal OvertimeHours { get; set; }
[TypeConverter(typeof(PayRateConverter))]
public decimal OvertimeRate { get; set; }
// many many more
}
CsvHelper
您的数据模型的属性,您可以使用自定义属性,如下所示:
public static class NumericType
{
public const string Dollars = "{0:0.00}";
public const string Hours = "{0:0.000}";
public const string PayRate = "{0:0.0000}";
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DecimalFormatAttribute : System.Attribute
{
public string Format { get; } = "{0}";
public DecimalFormatAttribute(string format) => Format = format;
}
public class MyDecimalConverter : DefaultTypeConverter
{
public string Format { get; } = "{0}";
public MyDecimalConverter(string format) => Format = format;
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
if (value is decimal d)
return (d == 0) ? string.Empty : string.Format(Format, d);
return base.ConvertToString(value, row, memberMapData);
}
}
public static class CsvHelpExtensions
{
public static void RegisterDecimalFormats<T>(this ClassMap<T> map)
{
foreach (var property in typeof(T).GetProperties())
{
var attr = property.GetCustomAttribute<DecimalFormatAttribute>();
if (attr != null)
map.Map(typeof(T), property, true).TypeConverter(new MyDecimalConverter(attr.Format));
}
}
}
class PayrollRecord
{
public int EmployeeID { get; set; }
[DecimalFormat(NumericType.Dollars)]
public decimal RegularPay { get; set; }
[DecimalFormat(NumericType.Hours)]
public decimal RegularHours { get; set; }
[DecimalFormat(NumericType.PayRate)]
public decimal RegularRate { get; set; }
[DecimalFormat(NumericType.Dollars)]
public decimal OvertimePay { get; set; }
[DecimalFormat(NumericType.Hours)]
public decimal OvertimeHours { get; set; }
[DecimalFormat(NumericType.PayRate)]
public decimal OvertimeRate { get; set; }
// many many more
}
var classMap = new DefaultClassMap<PayrollRecord>();
classMap.AutoMap(); // Do this before RegisterDecimalFormats
classMap.RegisterDecimalFormats();
enum
对于十进制格式,我使用了一系列 const string
格式简单。 [Format("..")]
注释每个字段。属性,但为了获得我正在寻找的零抑制,格式字符串是一个由三部分组成的丑陋东西,看起来非常容易出错并且更改起来非常乏味。
public const string
如上所示的格式可用于简化代码并避免重复的格式字符串。
关于c# - 将自定义字段属性添加到 CsvHelper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59459629/
CSVHelper v23 中的重大更改包括“所有委托(delegate)现在都接受单个结构参数”。 PrepareHeaderForMatch 是这些委托(delegate)之一。我收到编译错误“委
我正在尝试使用 CsvHelper 来改进我从对象到 csv 记录/行的手动转换过程。我创建了一个复杂的 ClassMap我想用它来将对象列表写入文件。如何添加 ClassMap到 CsvHelper
我有一个使用 CSVHelper (v19.0.0) 的类库。我在 VS2019(版本 16.5.5;.NET 4.8.03752)中通过 Nuget 安装了 CSVHelper,并且可以确认该包位于
我有一个使用 CSVHelper (v19.0.0) 的类库。我在 VS2019(版本 16.5.5;.NET 4.8.03752)中通过 Nuget 安装了 CSVHelper,并且可以确认该包位于
我正在使用 CsvHelper 将小巧的对象转换为 CsvFile。我正在使用类映射来映射索引和名称映射的属性。问题是在按如下所述写入记录之前,我需要带有表标题的行: 没有标题的旧代码: usin
您好,我正在尝试使用 CsvHelper,并最终将我的数据写入 .csv 文件,但如果尝试读取数据,结果总是空的。它读取 header ,然后 csv.Read() 似乎跳过了所有数据。 Sperrn
在 CsvHelper 的早期版本中,我可以像这样设置默认分隔符: using var csv = new CsvReader(reader, CultureInfo.CurrentCulture);
我正在使用 CsvHelper 我需要用引号包裹所有值。 那可能吗? 数据 = 是一个列表 using (StreamWriter textWriter = new StreamWriter(pat
我正在尝试读取上传的 CSV 文件,在对数据执行任何操作之前,我需要检查第一个 header 名称以确保它是正确的文件。我一直在试图找到一种方法来做到这一点,但读者却跳到第二行。有没有直接选择其中一个
我的文件中有以下格式的数据。 HEADER|ReportItem Name: Margin Ri..... Account Id/Margin Id|Account Name|Ba...... //
我正在使用出色的 CsvHelper 库(当前为 v12.2.2)来生成 CSV 文件,并且我正在尝试添加我自己的自定义属性以直接在类中指定特殊格式。 我正在写的记录看起来像这样(尽管集成需要大约 2
我在变量中有一个字符串,而不是在文件中。 我可以使用 CSVHelper ( https://joshclose.github.io/CsvHelper/ ) 来解析字符串并将其映射到我的对象上吗?
我正在成功使用类CsvReader并对此感到满意,但是,我使用的文件是由一个小组生成的,该小组在不通知我的情况下更改了列格式。 因此,一会儿一切正常,然后第二天早上事情中断,csv.GetRecord
我正在尝试读取逗号分隔的 csv 文件,除非字段包含逗号,否则该文件在大多数情况下都不是文本限定的。一个例子是可以包含逗号的地址行。当发生这种情况时,列将在我的映射对象内分流。 AddressLine
我对 .NET 的 CsvMapper 有疑问。我正在使用类映射器将对象映射到这样的 csv 文件中: Map(x => x.ProductId).Name("ProductId"); 这工作正常,但
我对 .NET 的 CsvMapper 有疑问。我正在使用类映射器将对象映射到这样的 csv 文件中: Map(x => x.ProductId).Name("ProductId"); 这工作正常,但
我正在尝试将 CsvWriter 配置为使用特殊字符串“#NULL#”作为可为 null 的字符串属性。对于读者来说,它可以通过设置 csvReader.Configuration.TypeConve
我有一项服务接受包含需要批量插入数据库的 CSV 数据的输入流,并且我的应用程序尽可能使用 async/await。 过程是:使用CsvHelper的CsvParser解析流,将每一行添加到DataT
我有以下 CSV。 Org Defined ID,Username,FirstName,LastName,Attempt #,Attempt Start,Attempt End,Section #,Q
我有一个不可变类,我想写入和读取 CSV 文件。问题是我在读取 CSV 时遇到异常,尽管已经映射了对象并设置了一个应该允许它工作的配置。 为此,我使用 CsvHelper .不可变类如下所示。 pub
我是一名优秀的程序员,十分优秀!