@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

もう解決済み?「ファイルのダウンロード」二度表示

1
投稿者投稿内容
naomix
ベテラン
会議室デビュー日: 2003/02/01
投稿数: 56
投稿日時: 2004-03-10 21:43
IEから抽出条件を入力し、抽出したデータを編集したExcelファイルをダウンロードする処理を
ASP.NETで作っています。
下のようなコードでExcelファイルをダウンロードさせますと、
コード:
Response.Clear();
Response.ContentType="Application/x-msexcel";
Response.AppendHeader("content-disposition","attachment; filename=" + HttpUtility.UrlEncode(filename));
Response.WriteFile(outFileName);


「ファイルのダウンロード」ポップアップ画面が表示され、
”開く”を押すともう一度、「ファイルのダウンロード」ポップアップ画面が表示されてしまいます。

以下のスレッドと同じ現象です。
「webブラウザへファイルのダウンロード」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=5430&forum=7

上記スレッドでは、
解決したのは「子画面のブラウザが残ったまま」の問題の方で、
「ダウンロード画面二度表示」の問題は解決してないように
私には感じられるのですが。
というのは、上記スレッドのサーバー側のコードと、私のものと
本質的な違いはないような気がするからです。

また、
「データのダウンロード画面が二度表示される(ASP.NET)」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6801&forum=7

にあるように、
attachmentを、inlineに変えると、確かに一度しか表示しなくなりますが、
IE内にExcelが表示されるため、条件入力画面が消えてしまいます。
次の入力ができなくなるので、これは困ります。


「ファイルのダウンロード」ポップアップ画面をよく見てみると、
「この種類のファイルであれば常に警告する」というチェックボックスが
1度目はグレーアウトされて、オン・オフできない状態になっており、
2度目の表示では、グレーアウトされていなくて、オン・オフできる状態になっています。

また、
1回しか出ないクライアントパソコンもあったりします。

なんで2回出ちゃうんでしょうかね?
ton
常連さん
会議室デビュー日: 2004/01/20
投稿数: 29
投稿日時: 2004-03-11 09:10
'エンコードの指定
Response.ContentEncoding = System.Text.Encoding.GetEncoding("shift-jis")
'出力方式の設定
Response.ContentType = "application/octet-stream-dummy"
'ファイル名の指定
Response.AppendHeader("Content-Disposition", "inline; filename=" & strFilename & ".csv")

私も以前同じ問題で悩んでいました。
私はこれでいけましたけど、どうですか??
naomix
ベテラン
会議室デビュー日: 2003/02/01
投稿数: 56
投稿日時: 2004-03-11 11:15
どうもありがとうございます。

引用:

tonさんの書き込み (2004-03-11 09:10) より:
'エンコードの指定
Response.ContentEncoding = System.Text.Encoding.GetEncoding("shift-jis")
'出力方式の設定
Response.ContentType = "application/octet-stream-dummy"
'ファイル名の指定
Response.AppendHeader("Content-Disposition", "inline; filename=" & strFilename & ".csv")

私も以前同じ問題で悩んでいました。
私はこれでいけましたけど、どうですか??


早速やってみたのですが、
これって、ポイントは Content-Disposition の inline ですよね。
Content-Disposition は attachment のままで
Response.ContentEncoding と Response.ContentType の設定を変えても
予想通り、ダメでした。
しかしinlineにしてしまうと、最初に書いたように、IE上でExcelを実行してしまうので、
抽出条件入力とExcel出力を1つのページで実行すると、
抽出条件入力画面が消えてしまって、困るんです。

抽出条件入力とExcel出力を別のページで実行することにして、
抽出条件入力ページから、JavaScriptでwindow.openして、
Excel出力ページを実行すれば、抽出条件入力画面が消えずに
済むかもしれません。
しかしそうすると、抽出条件入力ページからExcel出力ページに抽出条件を
渡さなければならないので、ちょっとだけ面倒です(本当に「ちょっとだけ」ですが)。

「ダウンロード画面二度表示」の根本的な原因さえわかれば
対策も立てられるのですが。
ton
常連さん
会議室デビュー日: 2004/01/20
投稿数: 29
投稿日時: 2004-03-11 11:56
根本的な原因はこのページが参考になりませんか?
http://support.microsoft.com/default.aspx?scid=kb;ja;238588

私の場合、Content-Dispositionがinlineなのにattachment の処理ができてるんですよ。
きちんとIE外でExcelを実行できてます。
ちょっと怖い気がしますが・・・


naomix
ベテラン
会議室デビュー日: 2003/02/01
投稿数: 56
投稿日時: 2004-03-11 20:51
しまった。そんな情報が出ていたのですね。調査不足でした。
すみません。参考になりました。
これを見て、
よもやと思って、GETでダウンロードしてみたら、
1回しか出ませんでした。

POSTだと2回出て、GETだと1回しか出ない。
よく訳はわかりませんが、そういうことなのでしょうかね?
ういちゅ
会議室デビュー日: 2004/05/28
投稿数: 1
投稿日時: 2004-05-28 11:36
かなり遅くなってしまったレスですが…。
ASP.NET 側のコーディングによる回避を行うなら、こんなのはどうでしょうか?
まえに私が人に聞かれて、答えた内容です。(その人が見てたらここからぱくったって思うかも…)

参考になるかどうかわかりませんけど、参考になったらうれしいです。

POST を GET に変更する方法を用いた場合はボタンを押して処理をさせる必要がある場合は、動作しないことになります。
この現象は POST 時に発生するので、別にダウンロード用のページを用意してそのページで GET を用いることによってダウンロードのリクエストを行えば対処できます。
初回リクエストをされた ASPX ページ上の Page_Load 内でダウンロード用に GET メソッドを用いた ASPX ページを呼び出し、このダウンロード用の ASPX ファイル内でダウンロード処理をさせることで本現象を回避させることができます。
以下が手順です。

1. 各ダウンロードが必要な場合、ダウンロード対象ファイル分の ASPX ページを用意するです。
各ページ内の Page_Load イベントハンドラ中にダウンロード処理を記述してください。

例)test_xls.aspx (ダウンロード用のページです。Form の method プロパティを GET にしておいてください。)
private void Page_Load(object sender, System.EventArgs e)
{
// ページを初期化するユーザー コードをここに挿入します。
string filename = MapPath("Test.xls");
if(System.IO.File.Exists(filename))
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filename);
long nSize = fileInfo.Length;

Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename=Test.xls");
Response.WriteFile(filename, 0, nSize);
Response.End();
}
}

2. 処理を行うページ(ボタンのあるページ)をリクエスト。
3. ASPX ページ上でボタンをクリックします。POSTBACK が発生 (POST Request)。
4. Button_Click イベント ハンドラで、以下の処理を行う。

Response.Redirect(<ダウンロード対象ファイルのページ>)

例)ボタンが押されたときの処理。ダウンロード用の ASPX ファイルにリダイレクトさせる。
実際のダウンロード処理は test_xls.aspx ファイルで行われる。
private void Button1_Click(object sender, System.EventArgs e)
{
Response.Redirect("test_xls.aspx");
}

この方法を応用すれば、各ファイルごとではなく GET 用のひとつのダウンロード用の ASPX ファイルで対応することが出来ます。
たとえばダウンロードファイル名を変数にしておき、ダウンロードファイルのボタンに埋め込んだファイル名を QueryString などから取得してセットする方法なども考えられます。

#書き込み初めてな上 ASP.NET 初心者です。
#皆様今後とも宜しくお願いします。
naomix
ベテラン
会議室デビュー日: 2003/02/01
投稿数: 56
投稿日時: 2004-05-30 21:00
ういちゅさん、どうもありがとうございます。
私共も結局同様な解決策を講じました。
違うのは、test_xls.aspx に相当するところを、HTTPハンドラーにしたくらいで、
本質的には同じです。
この方法で気に入らないのは、
たかが、「ファイルのダウンロード」を二度表示させたくないだけのことで
不本意にも、サーバ-ブラウザ間を2往復することです。
とても無駄な通信です。
は〜、忌々しい。もっとエレガントにできないものか。
1

スキルアップ/キャリアアップ(JOB@IT)