0

I am trying to write data to csv file. I want the data to be displayed in double quotes when opened in notepad, but it shouldn't show any double quotes when I open the file in csv.

following is the code that I am using but, it doesn't give the result.

csvFile.WriteField("\"" +data.FirstName == null ? string.Empty : data.FirstName + "\"");

Can someone help me out with this?

user2083386
  • 135
  • 3
  • 19
  • It looks like there's a configuration option and an override for `WriteField` to force quoting. Use one of those. – Retired Ninja Jun 18 '20 at 22:35
  • 1
    There are a lot of other answers (like [this one](https://stackoverflow.com/q/3905946/3791245)) talking about how to get quotes into strings. But I think your problem is how you're using the ternary operator `a ? b : c`. Try adding parentheses around it, such as: `"\"" + (data.FirstName == null ? string.Empty : data.FirstName) + "\""`. Order of operations is likely checking if `"\"" + data.Firstname == null`, which it never is, because the resulting string always at least has a double-quote in it. – Sean Skelly Jun 18 '20 at 22:36

3 Answers3

2

The problem is you are trying to fight CsvHelper's quoting. According to the RFC 4180 specifications.

  1. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes. For example:
       "aaa","b CRLF
       bb","ccc" CRLF
       zzz,yyy,xxx
  1. If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote. For example:
       "aaa","b""bb","ccc"

So when you add double quotes to the field, CsvHelper recognizes that the whole field needs to be enclosed in double quotes and the added quotes need to be escaped with another double quote. That is why you end up with 3 double quotes.

CsvHelper has a configuration function where you can tell it when it should quote a field. @JoshClose already has an answer here for wrapping all fields in double quotes. I'll update it for the current version of CsvHelper.

void Main()
{
    var records = new List<Foo>
    {
        new Foo { Id = 1, Name = "one" },
        new Foo { Id = 2, Name = "two" },
    };

    using (var writer = new StringWriter())
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        csv.Configuration.ShouldQuote = (field, context) => true;
        csv.WriteRecords(records);

        writer.ToString().Dump();
    }
}

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}

If you still wanted to add the double quotes yourself, you could turn off CsvHelper's double quoting.

csv.Configuration.ShouldQuote = (field, context) => false;

Breaking change for Version 20.0.0 and later

Changed CsvConfiguration to a read only record to eliminate threading issues.

You would need to create CsvConfiguration, set ShouldQuote on initialization and then pass it to the CsvWriter.

void Main()
{
    var records = new List<Foo>
    {
        new Foo { Id = 1, Name = "one" },
        new Foo { Id = 2, Name = "two" },
    };
    
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        ShouldQuote = (field, context) => true
    };

    using (var writer = new StringWriter())
    using (var csv = new CsvWriter(writer, config))
    {
        csv.WriteRecords(records);

        writer.ToString().Dump();
    }
}

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Community
  • 1
  • 1
David Specht
  • 7,784
  • 1
  • 22
  • 30
  • Thanks a lot. The following line worked for me in my case "csv.Configuration.ShouldQuote = (field, context) => true;" – user2083386 Jun 22 '20 at 13:08
  • This gives me the following error: `Property or indexer 'IWriterConfiguration.ShouldQuote' cannot be assigned to -- it is read only` – agileMike May 04 '21 at 20:28
  • There was a breaking change with Version 20.0.0. I added an update with the changes. – David Specht May 06 '21 at 14:30
0

I made code a bit more readable by placing the assignment of firstName to a variable that will be passed later. I used a string escape to add a quote to the final result. Now you can pass it to your WriteField method.

More information about string escape can be found: here and here.

var firstName = data.FirstName == null ? string.Empty : data.FirstName;
var firstNameWithQuoutes = $@"""{firstName}""";
Krystian Sitek
  • 573
  • 3
  • 7
  • Thanks for your response. I tried your solution, but still it didn't work. I am getting the result in notepad as """test""", which is having 3 double quotes, and in csv file, it is displaying as "test" for the firstname – user2083386 Jun 18 '20 at 22:57
0

Using the CsvConfiguration, you can change the CSV file configuration. To add the double quotes set the ShouldQuote=true, and to remove set ShouldQuote=false.

Plz try this in the latest version, I tried it in V28, and its works for me

var config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                ShouldQuote = (field) => false //Set the false to remove the double quotes
            };
            using (StreamWriter _streamWriter = new StreamWriter(fileNamePath))
            {
                using (var _csvWriter = new CsvWriter(_streamWriter, config))
                {
                    await _csvWriter.WriteRecordsAsync(models);
                }
            }
Jai
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 20 '23 at 07:07