最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Newest CsvHelper configuration changed several members to readonly and causes compilation errors on existing code - Stack O

programmeradmin4浏览0评论

The following C# code used to work with csvReader where variable reader is a StreamReader:

DataTable dataTable = null;
this._csvHeaders = null;

using (reader)
{
    using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        csv.Configuration.HasHeaderRecord = true;
        csv.Configuration.MissingFieldFound = (field, index, context) => AddMissingFieldParseError(field, context.Row, index);
        csv.Configuration.BadDataFound = (context) => AddBadDataFoundParseError(context.Field, context.Row);

        using (CsvDataReader dataReader = new CsvDataReader(csv))
        {
            // Validate headers
            this._csvHeaders = csv.Context.Reader.HeaderRecord.ToList();
            TrimHeaderNames(ref _csvHeaders);

            string errorMessage = string.Empty;

            if (!ValidateHeaders(_csvHeaders, out errorMessage))
            {
                XOperationError operationError = new XOperationError("Duplicated error found", errorMessage);
                this.ParseErrors.Clear();
                this.ParseErrors.Add(0, new List<XOperationError> { operationError });
                return null;
            }

            dataTable = new DataTable();
            dataTable.Load(dataReader);
        }
    }
}

Now it no longer works as HasHeaderRecord, MissingFieldFound, BadDataFound all became read-only.

I tried to remove the 3 lines and added the following before the new CsvReader() statement:

CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                HasHeaderRecord = true,
                MissingFieldFound = (field, index, context) => AddMissingFieldParseError(field, context.Row, index),
                BadDataFound = (context) => AddBadDataFoundParseError(context.Field, context.Row)
            };

Now it complains:

  1. MissingFieldFound does not take 3 arguments
  2. BadDataFoundArgs does not contain a definition for row

I'm really confused. Are these just syntax errors?

Any help is appreciated.

The following C# code used to work with csvReader where variable reader is a StreamReader:

DataTable dataTable = null;
this._csvHeaders = null;

using (reader)
{
    using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        csv.Configuration.HasHeaderRecord = true;
        csv.Configuration.MissingFieldFound = (field, index, context) => AddMissingFieldParseError(field, context.Row, index);
        csv.Configuration.BadDataFound = (context) => AddBadDataFoundParseError(context.Field, context.Row);

        using (CsvDataReader dataReader = new CsvDataReader(csv))
        {
            // Validate headers
            this._csvHeaders = csv.Context.Reader.HeaderRecord.ToList();
            TrimHeaderNames(ref _csvHeaders);

            string errorMessage = string.Empty;

            if (!ValidateHeaders(_csvHeaders, out errorMessage))
            {
                XOperationError operationError = new XOperationError("Duplicated error found", errorMessage);
                this.ParseErrors.Clear();
                this.ParseErrors.Add(0, new List<XOperationError> { operationError });
                return null;
            }

            dataTable = new DataTable();
            dataTable.Load(dataReader);
        }
    }
}

Now it no longer works as HasHeaderRecord, MissingFieldFound, BadDataFound all became read-only.

I tried to remove the 3 lines and added the following before the new CsvReader() statement:

CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                HasHeaderRecord = true,
                MissingFieldFound = (field, index, context) => AddMissingFieldParseError(field, context.Row, index),
                BadDataFound = (context) => AddBadDataFoundParseError(context.Field, context.Row)
            };

Now it complains:

  1. MissingFieldFound does not take 3 arguments
  2. BadDataFoundArgs does not contain a definition for row

I'm really confused. Are these just syntax errors?

Any help is appreciated.

Share Improve this question edited Mar 21 at 5:39 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 20 at 23:49 T. J. FanT. J. Fan 777 bronze badges 1
  • github/JoshClose/CsvHelper/blob/… – Hans Passant Commented Mar 20 at 23:57
Add a comment  | 

2 Answers 2

Reset to default 1

The call to csv.Configuration actually returns an IReaderConfiguration which is an interface implemented by the underlying CsvConfiguration class. As far as I can tell this was changed in 20.0.0 to avoid threading issues.

The idea is that the Configuration is immutable once it's been passed to the reader. So if you want to change it, you have to inject it (as you've mentioned):

using (reader){    
    var configuration = new CsvConfiguration(CultureInfo.InvariantCulture);
    // Note the culture is now in the configuration
    // Set up the rest of your configuration here

    using (CsvReader csv = new CsvReader(reader, configuration))    {
        // etc.

MissingFieldFound now takes 1 argument, MissingFieldFoundArgs. BadFoundData takes BadDataFoundArgs. It looks like that last one now has a Field, RawRecord and Context. I think Context.Reader might have the info you're looking for with respect to the row, if the context doesn't. Try this:

MissingFieldFound = (args) => AddMissingFieldParseError(args), // MissingFieldFoundArgs
BadDataFound = (args) => AddBadDataFoundParseError(args) // BadDataFoundArgs

Debug those args and you will be able to see what information you can retrieve from them. But setting them up before the using call is the right thing to do.

(You can see the list of changes in the changelog in case you run into further issues.)

I was able to figure out the parameters finally. Here are the solutions:

CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = true,
    MissingFieldFound = (args) => AddMissingFieldParseError(args.Context.Reader.HeaderRecord, args.Context.Reader.Parser.Row, args.Index),
    BadDataFound = (args) => AddBadDataFoundParseError(args.Field, args.Context.Reader.Parser.Row)
};

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论