Search code examples
c#csvhelperc#-9.0

C# record type not supported?


With a C# record defined as

public record Traffic(TrafficType Type, string Wan, string Lan, string Domain, string Org, IPAddress SrcIp, string SrcMac, IPAddress DestIp,
        string Protocol, string Scheme);

When I attempt to write a collection of them via

var all = new List<Traffic>();
// ...populate all
using var writer = new StreamWriter("file.csv");
using var csv = new CsvHelper.CsvWriter(writer, CultureInfo.InvariantCulture);
csv.WriteRecords(all);

I get an exception with the following message:

An unexpected error occurred. IWriter state: Row: 1 Index: 0
HeaderRecord: 1

If I convert the collection of record objects to a collection of class objects, then it succeeds. (trying to pass a record instance in to a class constructor didn't work. I had to create a class constructor that took every property of interest from the record instance as an explicit argument)

This is a .NET Core 5.0 project using CsvHelper 27.2.1.

Am I correct in concluding that the C# record type is not supported by CsvHelper?

Thank you.


Solution

  • The issue is not with record. The issue is the AutoMap of IPAddress. If you create a class with properties of IPAddress, you will get the same error. I'm not sure why AutoMap throws an exception, it works fine if you manually map all of the properties. The inner exception of the error is Value cannot be null. (Parameter 'source').

    void Main()
    {
        var all = new List<Traffic>()
        {
            new (TrafficType.Type1, "Wan1","Lan1","Domain1","Org1",IPAddress.Parse("192.168.0.1"), "SrcMac1",IPAddress.Parse("192.168.0.1"), "Protocol1", "Scheme1")
        };
    
        using var csv = new CsvHelper.CsvWriter(Console.Out, CultureInfo.InvariantCulture);
        
        csv.Context.RegisterClassMap<TrafficMap>();
              
        csv.WriteRecords(all);
    }
    
    public class TrafficMap : ClassMap<Traffic>
    {
        public TrafficMap()
        {
            //AutoMap(CultureInfo.InvariantCulture); // This will throw an exception.
            Map(x => x.Type);
            Map(x => x.Wan);
            Map(x => x.Lan);
            Map(x => x.Domain);
            Map(x => x.Org);
            Map(x => x.SrcIp);
            Map(x => x.SrcMac);
            Map(x => x.DestIp);
            Map(x => x.Protocol);
            Map(x => x.Scheme);
        }
    }
    
    public record Traffic(TrafficType Type, string Wan, string Lan, string Domain, string Org, IPAddress SrcIp, string SrcMac, IPAddress DestIp,
            string Protocol, string Scheme);
        
    public enum TrafficType
    {
        Type1,
        Type2
    }