Open CruseCtrl opened 10 months ago
Have you looked at CsvConfiguration.PrepareHeaderForMatch
? e.g.
void Main()
{
string csvString = """
My Property
value
""";
CsvConfiguration config = new(CultureInfo.InvariantCulture)
{
PrepareHeaderForMatch = args => args.Header.Replace(" ", "")
};
using StringReader sr = new(csvString);
using CsvReader csv = new(sr, config);
var records = csv.GetRecords<MyClass>().ToList();
}
class MyClass
{
public string MyProperty { get; set; }
}
@Rob-Hague thanks. I had tried that, but it only seems to be used when reading a file and is ignored when writing to a file
I guess another solution would be to make PrepareHeaderForMatch
affect writing files as well, but that would be a breaking change to current behaviour so is a bit more risky
Yeah that would be a bit strange. Personally I think your solution is totally valid, but I would probably tweak it slightly:
var map = csv.Context.AutoMap<SalesMasterExportRow>(); // this ensures the context is passed when mapping
foreach (var memberMap in map.MemberMaps)
{
memberMap.Data.Names.Clear();
memberMap.Data.Names.Add(GetHeaderName(memberMap.Data.Member?.Name));
}
// This is no longer necessary
// csv.Context.RegisterClassMap(map);
But that would override any existing name mapping which may not be desired. I think your configuration idea would work as well. I am not a maintainer so can't comment on whether it would be accepted.
The problem is that I still want to be able to override the default by using a [Name]
attribute. Most of my fields have a predictable mapping, but not all of them.
I see that there are already 19 open PRs, so I'm a bit worried that any work I do will just get ignored and be a waste of time. The last time a PR was merged was December last year :(
Is your feature request related to a problem? Please describe. When writing a csv, I want most of my header names to be a transformed version of my property names, e.g. in camelCase, or "Title Case", but I don't want to have to type these all out manually in
Name
attributes or in a class mapDescribe the solution you'd like It would be nice if I could do something like
and then I could write my own
GetHeaderName
function which would take e.g.MyPropertyName
and convert it intomyPropertyName
orMy Property Name
. Then I wouldn't have to have a[Name("My Property Name")]
attribute or use a class mapDescribe alternatives you've considered This works, but is a bit long-winded and requires me to know a bit more about how CsvHelper uses its maps:
Additional context It looks like the default name of a member gets set in
ClassMapCollection.SetMapDefaults
:This could be changed to
I'm happy to raise a pull request if this is something that's likely to get accepted? I'm not sure whether
GetDefaultHeaderName
is the best name for it though, so I'm open to other suggestions