CsvHelper Configuration.ShouldQuote - return 仅适用于 DTO 上的字符串字段

CsvHelper Configuration.ShouldQuote - return true for only fields on the DTO which are strings

您好,您有一个 DTO 对象,其中包含许多不同类型的属性,stringintbool

我只想在 string 属性周围应用双引号。

Configuration.ShouldQuote中,field参数值都被转换为string,所以无法知道来自DTO的原始类型是否是string, intbool.

有没有一种方法可以从 DTO 中找到基础 属性 类型,以便我可以从 Configuration.ShouldQuote 传回 true 仅用于最初类型为 [=] 的字段14=]?

public class TestDTO
{
    public string Field1 { get; set; }
    public int Field2 { get; set; }
    public bool Field3 { get; set; }
}
    var rawData = new[]
    {
        new TestDTO { Field1 = "Field1", Field2 = 1, Field3 = true },
        new TestDTO { Field1 = "Field2", Field2 = 10, Field3 = false }
    };
    using (var writer = new StreamWriter("file.csv"))
    {
        using (var csv = new CsvWriter(writer))
        {
            csv.Configuration.ShouldQuote = (field, context) =>
            {
                return field is string; // doesn't work as all fields at this point are strings
            };

            csv.WriteRecords(rawData);
        }
    }
csv.Configuration.ShouldQuote = (field, context) =>
{
    var index = context.Record.Count;
    var type = ((PropertyInfo)context.WriterConfiguration.Maps.Find<TestDTO>().MemberMaps[index].Data.Member).PropertyType;
    if (type == typeof(string))
    {
        return true;
    }

    return ConfigurationFunctions.ShouldQuote(field, context);
};

您也可以使用自定义转换器。

public class QuoteStringConverter : StringConverter
{
    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        var innerQuotes = ((string)value).Replace(row.Configuration.QuoteString, row.Configuration.DoubleQuoteString);
        var quotedValue = row.Configuration.Quote + innerQuotes + row.Configuration.Quote;
        return base.ConvertToString(quotedValue, row, memberMapData);
    }
}

关闭引号并将您的转换器添加到 TypeConverterCache

var rawData = new[]
{
    new TestDTO { Field1 = "Field1", Field2 = 1, Field3 = true },
    new TestDTO { Field1 = "Field2", Field2 = 10, Field3 = false }
};

using (var writer = new StreamWriter("file.csv"))
using (var csv = new CsvWriter(writer))
{
    csv.Configuration.ShouldQuote = (field, context) => false;
    csv.Configuration.TypeConverterCache.AddConverter<string>(new QuoteStringConverter());

    csv.WriteRecords(rawData);
}        

CsvHelper 已多次更改 ShouldQuote 行为,并且 Version 23 再次将此行为从具有多参数委托的行为更改为具有 ShouldQuoteArgs 类型的单个参数的行为.

引用所有非空字符串的非常简单的示例:

    ...
    var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        ShouldQuote = args =>
        {
            if (string.IsNullOrEmpty(args.Field)) return false;

            return args.FieldType == typeof(string);
        }
    };

CsvHelper 源代码中的默认 ShouldQuote 处理程序是查找处理引用的更多方法的好地方。