15

動的に生成されたファイルをダウンロードするコントローラー アクションがあります。

    public ActionResult DownloadFile()
    {
        var obj = new MyClass { MyString = "Hello", MyBool = true };
        var ser = new XmlSerializer(typeof(MyClass));
        var stream = new MemoryStream();
        ser.Serialize(stream, obj);
        stream.Position = 0;

        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=myfile.xml");
        Response.ContentType = "application/xml";

        // Write all my data
        stream.WriteTo(Response.OutputStream);
        Response.End();

        return Content("Downloaded");
    }

参考までに:

    public class MyClass
    {
        public string MyString { get; set; }
        public int MyInt { get; set; }
    }

これは機能しており、ファイル (myfile.xml) がダウンロードされます。
ただし、「ダウンロード済み」というメッセージはブラウザに送信されません。

同様に、return Content("Downloaded");
forを置き換えるとreturn Redirect("www.something.com");
、ファイルがダウンロードされる前にブラウザーがリダイレクトされます。

少し前提として、ユーザージャーニーは次のとおりです。

  • ユーザーが前のビューでフォームに入力
  • フォームが送信されました
  • XML が生成され、ダウンロードされます
  • ユーザーがリダイレクトされ、「ダウンロード済み」ビューが表示されます(F5 キーを押してもフォームは再投稿されません)。
4

3 に答える 3

11

Ross が言ったように、HTTP リクエストに対して返せるレスポンスは 1 つだけです。その場合に私がすることは次のとおりです。

  1. リクエストをサーバーに送信する
  2. サーバーはファイルを生成し、サーバー側のデータ構造 (Cache、Usersession、TempData) に保存します。
  3. サーバーはRedirectToAction()(POST、REDIRECT、GET パターン) を返します。
  4. リダイレクトされたアクションは、JavaScript を含むビューを返します。
  5. window.location.hrefプロパティを特別なダウンロード アクションに設定して、ファイルをブラウザに送り返すことにより、事前に生成されたファイルのダウンロードをトリガーします。
于 2012-10-31T16:29:25.387 に答える
9

各 HTTP リクエストには 1 つの応答しかありません。2 つ (ファイルとページ) に忍び込もうとしています。

通常、「Content-Disposition: attachment」HTTP ヘッダーを送信すると、ブラウザーは現在のページにとどまり、ファイル保存ダイアログをポップします (または、ファイルをダウンロードに自動的に保存します)。

フォームの再送信を防ぎたい場合は、戦略を変更する必要があります。フォームの送信ボタンを無効にし、div オーバーレイに「完了」メッセージを表示するには、JavaScript を少し使用することをお勧めします。

于 2012-10-25T14:45:34.263 に答える