1

From my ASP.Net Core 3.1 Web API I am trying to export simple CSV file. For that I am using CsvHelper package where I generate MemoryStream with following method:

public async Task<MemoryStream> ExportAsync(IEnumerable records)
{
    byte[] content = null;
    using (var mem = new MemoryStream())
    using (var writer = new StreamWriter(mem, Encoding.GetEncoding("windows-1250")))
    {
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
            csvWriter.Configuration.Delimiter = "|";
            csvWriter.WriteField("sep=|", false);
            csvWriter.NextRecord();
            await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
            await csvWriter.FlushAsync().ConfigureAwait(false);
            await writer.FlushAsync().ConfigureAwait(false);
            content = mem.ToArray();
        }
    }

    var output = new MemoryStream(content);
    return output;
}

This is called from my Controller in the following method:

[HttpGet("GetCountriesAsCSV")]
[SwaggerResponse(400, typeof(string))]
[SwaggerResponse(typeof(File))]
public async Task<IActionResult> GetCountriesAsCSV()
{
    try
    {
        var allCountries = await countryManager.GetAllAsync();
        var transformedCountries = mapper.Map<IEnumerable<CountryCsv>>(allCountries);
        var stream = await csvExportService.ExportAsync(transformedCountries).ConfigureAwait(false);

        return File(stream, "text/csv", $"AllCountries{DateTime.Now.Ticks}.csv");
    }
    catch (Exception ex)
    {
        return StatusCode((int)HttpStatusCode.BadRequest, ex.Message);
    }
}

The problem is, that when I open exported CSV file from Excel, special characters are not displayed correctly (due to encoding). This is what output looks like:

enter image description here

I have tried to use exactly the same method to generate CSV file, but instead of pushing it back as MemoryStream, I saved file directly in current folder as following:

private async Task WriteAll(IEnumerable records)
{
    using (var writer = new StreamWriter("RobertFile.csv", true, Encoding.GetEncoding("windows-1250")))
    {
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
            csvWriter.Configuration.Delimiter = "|";
            csvWriter.WriteField("sep=|", false);
            csvWriter.NextRecord();
            await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
            await csvWriter.FlushAsync().ConfigureAwait(false);
            await writer.FlushAsync().ConfigureAwait(false);
        }
    }
}

As you can see, the only difference between ExportAsync and this WriteAll method are StreamWriter parameters (yet, with the exact same encoding specifications).

Once I open this file, it looks perfectly fine as visible below:

enter image description here

I don't quite understand, why encoding is lost when converted to MemoryStream and then exported as a File object result.

Any help in respect to this matter would be highly appreciated.

1 Answer 1

4

So as soon as I changed Content Type from text/csv to application/octet-stream as following:

return File(stream, "application/octet-stream", "AllCountries.csv");

It suddenly worked like a charm.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.