Search code examples
asp.net-web-apiexport-to-csvhttpresponsemessage

Downloading a csv file from Web API does not start


I have this sample code from different sources and I want to try it first before applying it to my code which is pretty similar to the samples I got.

I have the following codes in my controller:

[Route("getcsv")]
    [HttpGet]
    public HttpResponseMessage GetCSV()
    {
        var data = new[]{   //Suppose you filter out these data

                           new{ Name="Ram", Email="[email protected]", Phone="111-222-3333" },
                           new{ Name="Shyam", Email="[email protected]", Phone="159-222-1596" },
                           new{ Name="Mohan", Email="[email protected]", Phone="456-222-4569" },
                           new{ Name="Sohan", Email="[email protected]", Phone="789-456-3333" },
                           new{ Name="Karan", Email="[email protected]", Phone="111-222-1234" },
                           new{ Name="Brij", Email="[email protected]", Phone="111-222-3333" }
                  };

        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StringContent(WriteTsv(data));
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); //attachment will force download
        result.Content.Headers.ContentDisposition.FileName = "RecordExport.csv";


        return result;
    }

    public string WriteTsv<T>(IEnumerable<T> data)
    {
        StringBuilder output = new StringBuilder();
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
        foreach (PropertyDescriptor prop in props)
        {
            output.Append(prop.DisplayName); // header
            output.Append("\t");
        }
        output.AppendLine();
        foreach (T item in data)
        {
            foreach (PropertyDescriptor prop in props)
            {
                output.Append(prop.Converter.ConvertToString(
                     prop.GetValue(item)));
                output.Append("\t");
            }
            output.AppendLine();
        }
        return output.ToString();
    }

I am calling this method through the following:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

    <script type="text/javascript">
        function save() {
            window.open('https://localhost:44370/api/values/getcsv', '_blank', '');
        }
    </script>
</head>
<body>
    <a class="btn btn-primary" onclick="save()">Export</a>
</body>
</html>

All of these give me the following result instead of downloading a file:

enter image description here

I don't have any idea what I am missing. Please help! Thank you!


Solution

  • You are most likely using the wrong syntax for your version of Web API.

    If using Asp.Net Core Web API it would need to be refactored to

    [Route("api/[controller]")]
    public class ValuesController: Controller {
        //GET api/values/getcsv
        [Route("getcsv")]
        [HttpGet]
        public IActionResult GetCSV() {
            var data = new[]{   //Suppose you filter out these data
               new{ Name="Ram", Email="[email protected]", Phone="111-222-3333" },
               new{ Name="Shyam", Email="[email protected]", Phone="159-222-1596" },
               new{ Name="Mohan", Email="[email protected]", Phone="456-222-4569" },
               new{ Name="Sohan", Email="[email protected]", Phone="789-456-3333" },
               new{ Name="Karan", Email="[email protected]", Phone="111-222-1234" },
               new{ Name="Brij", Email="[email protected]", Phone="111-222-3333" }
            };
    
            var bytes = System.Text.Encoding.UTF8.GetBytes(WriteTsv(data));
            return File(bytes, "application/octet-stream", "RecordExport.csv");
        }
    
        //...code omitted for brevity
    
    }
    

    In Asp.Net Core HttpResponseMessage is no longer treated as a first class citizen of the pipeline and is being serialized like a normal model.