嗨,有一个DTO对象,其中包含许多不同类型的属性,string
,int
或bool
等。
我只想在string
属性周围应用双引号。
在Configuration.ShouldQuote
中,field
参数值都已转换为string
因此无法知道DTO的原始类型是string
,int
还是bool
。
有没有办法从 DTO 找到基础属性类型,以便我只能从 Configuration.ShouldQuote
传回最初属于 string
类型的字段的true
?
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);
}
}
CsvHelper 多次更改了ShouldQuote
行为,版本 23 再次将此行为从具有多参数委托的行为更改为具有 ShouldQuoteArgs
类型单个参数的行为。
一个非常简单的例子,引用所有非空字符串:
...
var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
ShouldQuote = args =>
{
if (string.IsNullOrEmpty(args.Field)) return false;
return args.FieldType == typeof(string);
}
};
CsvHelper 源中的默认ShouldQuote
处理程序是查找更多处理引用方法的好地方。
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);
}