No Silver Bullet

技術ブログを更新しているかっこいい人にあこがれて作りました。

【C#,MVC】作成したCSVをFileContentResultで返却すると画面にCSVの内容が出力される

どうもC# MVC初心者です。

今日は以下の目的に対して、こんな現実(問題)が発生。

目的:サーバーサイド(controller)で組み立てたCSVをクライアント側に投げて、ブラウザのダウンロードダイアログを出力したい!
現実:ブラウザのダウンロードダイアログは出力されず、ブラウザの画面にCSVの内容が出力される!

今日はそれを解決したいと思います!


実際の問題なコードはこちら。

【ExportController.cs】

public ActionResult Export()
{
    ActionResult result = null;

    string fileName = "test.csv";

    using (MemoryStream ms = new MemoryStream())
    using (var csvWriter = new StreamWriter(ms, Encoding.GetEncoding("shift-jis")))
    {
        csvWriter.WriteLine("a,b,c");
        csvWriter.WriteLine("d,e,f");

        // バッファに残ったストリームをすべて書き込む
        csvWriter.Flush();

        result = File(ms.ToArray(), "application/octet-stream");
    }

    return result;
}

特にエラーが出力されない問題なので、結構ハマりましたが最後の文を以下の通り書き替えたら普通にダイアログが出力されました。

result = File(ms.ToArray(), "text/csv");

結局、画面にCSVの内容が出力してしまった理由としては、FileContentResultでレスポンスをブラウザに返す時に、Content-Typeが「application/octet-stream」になっておりブラウザ側でCSVファイルと認識できなかったから画面に出力してしまったという感じみたいですね。

ちなみに、下のコードでもダウンロードダイアログは出力されました。

result = File(ms.ToArray(), "application/octet-stream","test.csv");


HTTPの仕組みを理解していればすぐに対応することができたと思われる問題でした。。。。
うーむ。クライアント側の仕組みはまだ理解できていないことが多いので日々精進ですね。。。