10

ASP.NETMVCでファイルのダウンロードを実装する必要があります。Webを検索すると、次のようなコードが見つかりました。

public ActionResult GetFile()
{
    return File(filename, "text/csv", Server.UrlEncode(filename));
}

それはいいことですが、このファイルの内容を動的に作成したいと思います。

ファイルを動的に作成し、上記の構文を使用してそのファイルをダウンロードできることに気付きました。しかし、単に自分のコンテンツを応答に直接書き込むことができれば、より効率的ではないでしょうか。これはMVCで可能ですか?

4

5 に答える 5

14

これは、私が使用することになったコードの過度に単純化されたバージョンです。それは私のニーズを満たしています。

[HttpGet]
public ActionResult GetFile()
{
    Response.Clear();
    Response.AddHeader("Content-Disposition", "attachment; filename=myfile.csv");
    Response.ContentType = "text/csv";

    // Write all my data
    Response.Write(...);
    Response.End();

    // Not sure what else to do here
    return Content(String.Empty);
}
于 2012-05-12T04:51:34.707 に答える
4

別の解決策は、ストリームを受け入れるFile()のオーバーロードを使用することです。

私の場合、コントローラーアクションから生成する必要があるのはcsvなので、次のようになります。

[HttpGet]
public ActionResult DownloadInvalidData(int fileId)
{
    string invalidDataCsv = this.importService.GetInvalidData(fileId);
    string downloadFileName = "error.csv";

    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);

    writer.Write(invalidDataCsv);
    writer.Flush();
    stream.Position = 0;

    return File(stream, "text/csv", downloadFileName);
}

StreamまたはStreamWriterをFile()関数に渡す前に破棄しないでください。どちらかを破棄すると、ストリームが閉じられて使用できなくなります。

于 2015-10-05T15:08:40.673 に答える
3

それがFileStreamResultが行うことだと私はかなり確信しています。ただし、使用したくない場合は、応答に書き込んでください。

于 2012-05-12T03:47:30.587 に答える
3

ファイルとしてダウンロードしたい場合ActionResultは、@ Tunganoが提案するようにカスタムを試すことができます。そうでない場合は、応答に直接入れたい場合は、組み込みでContentResult実行できますが、単純な文字列で機能し、複雑なシナリオではそれを拡張する必要があります。

public class CustomFileResult : FileContentResult
{
  public string Content { get; private set; }

  public string DownloadFileName { get; private set; }

  public CustomFileResult(string content, string contentType, string downloadFileName)
    : base(Encoding.ASCII.GetBytes(content), contentType)
  {
    Content = content;
    DownloadFileName = downloadFileName;
  }

  public override void ExecuteResult(ControllerContext context)
  {
    context.HttpContext.Response.AppendHeader("Content-Disposition", "attachment; filename=" + DownloadFileName);

    base.ExecuteResult(context);
  }
}


public class BlogController : Controller
{
  public ActionResult Index()
  {
    return View();
  }

  public CustomFileResult GetMyFile()
  {
    return CustomFile("Hello", "text/plain", "myfile.txt");
  }

  protected internal CustomFileResult CustomFile(string content, string contentType, string downloadFileName)
  {
    return new CustomFileResult(content, contentType, downloadFileName);
  }
}
于 2012-05-12T05:03:55.417 に答える
2

ファイルにストリーミングするのと同じように、Response.OutputStreamに直接書き込むことができます。テスト可能でMVCっぽい状態を維持するために、渡すモデルオブジェクトのストリーミングを行う独自のActionResultクラスを作成できます。

于 2012-05-12T04:06:43.007 に答える