Search code examples
c#export-to-csvmemorystream

Append memory stream with data byte to download in csv


I am trying to append the memory stream in a loop and then pass it to the HTTPResponseMessage as a csv file, however when i download the file, no data is displayed.

 var stream = new System.IO.MemoryStream();
                for (int i = 1; i <= pageCount; i++)
                {
                     search = GetSearch(searchResultParam);
                    csvContent = GetCsvForSearchResult(search);
                    byte[] data = System.Text.Encoding.UTF8.GetBytes(csvContent);
                    stream.Write(data, 0, data.Length);
                
            }
           

            string fileName = "Review" + "-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ".csv";
            var result = new System.Net.Http.HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new System.Net.Http.StreamContent(stream)
            };
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = fileName;
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
            result.Content.Headers.ContentLength = stream.Length;

But if I write it directly to the memory stream, the data is being downloaded.

var stream = new System.IO.MemoryStream();
                for (int i = 1; i <= pageCount; i++)
                {
                     search = GetSearch(searchResultParam);
                    csvContent = GetCsvForSearchResult(search);
                    byte[] data = System.Text.Encoding.UTF8.GetBytes(csvContent);
                    stream = new System.IO.MemoryStream(data); 

            }


            string fileName = "Review" + "-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ".csv";
            var result = new System.Net.Http.HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new System.Net.Http.StreamContent(stream)
            };
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = fileName;
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
            result.Content.Headers.ContentLength = stream.Length;

Solution

  • Seek the stream to the start before letting the client consume it

    var stream = new System.IO.MemoryStream();
                    for (int i = 1; i <= pageCount; i++)
                    {
                         search = GetSearch(searchResultParam);
                        csvContent = GetCsvForSearchResult(search);
                        byte[] data = System.Text.Encoding.UTF8.GetBytes(csvContent);
                        stream.Write(data, 0, data.Length);
                    
                }
                // will make the reads start at the beginning 
                stream.Seek(0, SeekOrigin.Begin);
               
                string fileName = "Review" + "-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ".csv";
                var result = new System.Net.Http.HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new System.Net.Http.StreamContent(stream)
                };
                result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
                result.Content.Headers.ContentDisposition.FileName = fileName;
                result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
                result.Content.Headers.ContentLength = stream.Length;