1

My initial requirement is to let the user download a file from object list for that I found this solution https://stackoverflow.com/a/49207997/11178128,

But the problem is when it comes to this line

bin = stream.ToArray();

there are no streams written to it. So the bin comes as an empty array. What could be the problem?

Also, I'm making my web API available through a windows service. And for some reason System.Web.HttpContext.Current.Response gives me null. any idea why it can be? Thanks in advance.

This is the code i have so far

List<Device> devices;

    using (StreamReader r = new StreamReader(String.Format(@"{0}\deviceList.json", savefilePath)))
    {
      string json = r.ReadToEnd();
      devices = JsonConvert.DeserializeObject<List<Device>>(json);
    }

    byte[] bin;
    //String.Format(@"{0}\devices.csv", savefilePath)
    using (MemoryStream stream = new MemoryStream())
    using (TextWriter textWriter = new StreamWriter(stream))
    using (CsvWriter csv = new CsvWriter(textWriter))
    {
      csv.Configuration.ShouldQuote = (field, context) => false;

      csv.WriteRecords(devices);
      bin = stream.ToArray();
    }
Bernard Vander Beken
  • 4,848
  • 5
  • 54
  • 76
Shehanmark
  • 41
  • 1
  • 6
  • Hi, since the `.ToArray` method is presumably working correctly, the issue is likely to be in the rest of your code. Please [edit] your question and provide us with more code-details :-) – Stefan Mar 10 '19 at 08:32
  • @Stefan Hey thanks for the quick response. yeah i updated my code here. – Shehanmark Mar 10 '19 at 09:37
  • Hmm... I am missing something; as far as I can see this should work. – Stefan Mar 10 '19 at 10:17
  • @Stefan yeah found the solution. I had to flush the StreamWriter. Posted the answer below. Thanks for the response. – Shehanmark Mar 18 '19 at 02:50

4 Answers4

1

This is related to another question, CsvHelper not writing anything to memory stream. You just need to change your using statements so that the StreamWriter gets flushed before calling stream.ToArray();

List<Device> devices;

    using (StreamReader r = new StreamReader(String.Format(@"{0}\deviceList.json", savefilePath)))
    {
      string json = r.ReadToEnd();
      devices = JsonConvert.DeserializeObject<List<Device>>(json);
    }

    byte[] bin;
    //String.Format(@"{0}\devices.csv", savefilePath)
    using (MemoryStream stream = new MemoryStream()) 
    {
       using (TextWriter textWriter = new StreamWriter(stream))
       using (CsvWriter csv = new CsvWriter(textWriter))
       {
         csv.Configuration.ShouldQuote = (field, context) => false;

         csv.WriteRecords(devices);
       }

       bin = stream.ToArray();
    }
David Specht
  • 7,784
  • 1
  • 22
  • 30
  • Hey thank you for the response and sorry for the delayed reply. I see by wrapping the textWriter in the second using block it automatically flushes the streamWriter ? thats cool. anyways i have posted what i use now as my solution think that is a good way to solve it. – Shehanmark Mar 18 '19 at 02:48
1

Actually, after a bit of struggling, Found that i was missing this line.

textWriter.Flush();

As mentioned in the below reply I had to flush the textWriter object in order to write to the file. Here is the working code.

  byte[] data;
  using (MemoryStream stream = new MemoryStream())
  using (TextWriter textWriter = new StreamWriter(stream))
  using (CsvWriter csv = new CsvWriter(textWriter))
  {
    csv.Configuration.RegisterClassMap<DeviceMap>();
    csv.Configuration.ShouldQuote = (field, context) => false;

    csv.WriteRecords(values);
    textWriter.Flush();
    data = stream.ToArray();
  }

  return data;
Shehanmark
  • 41
  • 1
  • 6
0
 using (var ms = new MemoryStream())
            {
                using (var writer = new StreamWriter(ms))
                using (var csv = new CsvWriter(writer))
                {
                    csv.WriteRecords(dbresponse);
                } // the closing tag here is important!!It flush the streamwriter
                 ms.ToArray(); // or ms.GetBuffer()
            }

Now the ms.ToArray() will contain the data from csvHelper

0

For a field variant - for example a list, which won't work using the writerecords method - you will need to use writefield. I am just submitting this here as this trifling issue caused me none too little pain.

Here is an async example:

var result = await GetListOfString();

        using (var ms = new MemoryStream())
        {
            using (var writer = new StreamWriter(ms))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                foreach (var value in result)
                {
                    csv.WriteField(value);
                    await csv.NextRecordAsync();
                }
         
                await writer.FlushAsync();
                return ms.ToArray(); 
            } 
        }