user23048345 user23048345 - 1 year ago 52 Question

ASP.NET CSV Excel issue with strange characters

I'm exporting a table of data to CSV format, e.g.:

"1","some text", "£232.00"
"2","some more text", "£111.00"
"3","other text", "£2.00"

The code to export is fairly simple using an ashx handler:

context.Response.ContentType = "text/csv"
context.Response.AddHeader("Content-disposition", "attachment;filename=data.csv")
context.Response.AddHeader("Cache-Control", "must-revalidate")
context.Response.AddHeader("Pragma", "must-revalidate")

My issue is when Excel tries to open the exported file the character
appears before all
signs, e.g.
when the value should be

Answer Source

You need to set the encoding i.e. the Response.ContentEncoding property.

After finally looking this up in Reflector, the default ContentEncoding is likely to be Encoding.Default or Encoding.UTF8, if a system.web/globalization config section exists, unless it is overridden by a responseEncoding property in that config section.

As to whether setting the ContentEncoding property at all performs differently to not doing so:

  • If you set it to the same object as its current setting, it explicitly catches that and does nothing;
  • However, if you change the setting, it calls HttpWriter.UpdateResponseEncoding, which calls HttpWriter.FlushCharBuffer before switching to the new encoding if there's anything buffered to write already.
  • If you do not set ContentEncoding it is set to the default I mentioned above by first reference to HttpWriter.UpdateResponseEncoding, which is definitely called before any content is written because HttpWriter._responseEncodingUpdated is checked in the writing methods and only updated to True at the end of HttpWriter.UpdateResponseEncoding.

As such, I believe the OP needed to change the encoding to Unicode and I assume Phil Hale's comment means he had a system.web/globalization config section that needed overriding.


  • The existing code calling Response.Clear only affects content, not headers, so, contrary to my previous suggestion, I don't believe it is relevant, other than removing any chance of existing content to be present to be flushed before the ContentEncoding change.
  • This is based upon the Reflector 6 output from System.Web from .NET Framework 2.0.