3

I am trying to download a csv file using web api 2 and angular js.

This is my controller code

public IHttpActionResult ExportCsvData()
{
    var stream = new FileStream("Testcsv.csv", FileMode.Open, FileAccess.Read);
    var response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new StreamContent(stream);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "Testcsv.csv"
    };

    return Ok(response);
 }

This is my angular code,

var filename = 'testcsv.csv';
var contentType = 'text/csv;charset=utf-8';
var blob = new Blob([data], { type: contentType });
if (navigator.msSaveBlob) {
    navigator.msSaveBlob(blob, filename);
}

I am using IE 11, but when I open the file in excel, it looks like this,

{   "version": {
    "major": 1
    "minor": 1
    "build": -1
    "revision": -1
    "majorRevision": -1
    "minorRevision": -1   }   "content": {
    "headers": [
      {
        "key": "Content-Type"
        "value": [
          "application/octet-stream"
        ]
      }
      {
        "key": "Content-Disposition"
        "value": [
          "attachment; filename=testcsv.csv"
        ]
      }
    ]

What am I doing wrong?

Thanks !

Nkosi
  • 235,767
  • 35
  • 427
  • 472
user636525
  • 3,180
  • 9
  • 38
  • 51

1 Answers1

7

You need to return a response message. The Ok() will serialize the HttpResponseMessage as is.

public IHttpActionResult ExportCsvData()
{

        var stream = new FileStream("Testcsv.csv", FileMode.Open, FileAccess.Read);
        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StreamContent(stream);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "Testcsv.csv"
        };

        return ResponseMessage(response);
 }
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    I see that you switched it from text/csv to application/octet-stream. Is that necessary? Or can you just use a new StringContent() instead of a new StreamContent() – Steve Apr 28 '16 at 22:10
  • They all eventually convert down to a stream. The `StreamContent` was used to match the file stream that was opened to get the file data. – Nkosi Apr 28 '16 at 22:16
  • ResponseMessage comes under which namespace? I can not find it – Neel Sep 17 '18 at 10:58
  • @Neel it is a method of the [`ApiController.ResponseMessage`](https://learn.microsoft.com/en-us/dotnet/api/system.web.http.apicontroller.responsemessage?view=aspnetcore-2.1#System_Web_Http_ApiController_ResponseMessage_System_Net_Http_HttpResponseMessage_), which is assumed to be used in the OP given the version of Web API being used. – Nkosi Sep 17 '18 at 11:00