質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

ASP.NET MVC 4

ASP.NET MVC4は、MVCパターンを利用して、高度なテスト機能と保守機能を備えた Web アプリケーションを開発するためのフレームワークです。

Q&A

解決済

2回答

17663閲覧

フルパスを指定したファイルダウンロード機能の実装方法について

f_horizon

総合スコア163

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

ASP.NET MVC 4

ASP.NET MVC4は、MVCパターンを利用して、高度なテスト機能と保守機能を備えた Web アプリケーションを開発するためのフレームワークです。

0グッド

0クリップ

投稿2017/06/02 06:55

編集2017/06/02 07:20

お世話になっております。
ASP.NET MVC5で、ボタンクリックによるサーバーにあるファイルのダウンロード機能を実装しています。
目標:
ボタンクリック -> サーバー処理でファイル名やパスの生成 -> パスのファイルをダウンロード
(よくあるブラウザの下部にダウンロードバーが表示され、[開く]か[名前を付けて保存]となる機能です。)

ファイルへのフルパスは取得しているのですが、色々試してもうまく実装できず。。。
jsによるクライアント側処理やASP.NET MVCの処理どちらでも構いません。ここを参考にしてとかでもあればお教えいただきたいです。
よろしくお願いいたします。

現状:以下のようにクライアント側でパス使ってできないかコネコネしている状況です。
(単純にlocation.hrefでやってみたり、aタグのエレメント作ってクリックしてみたり。。。)
また色々端折っていますが、以下のようなコードでajaxのdoneでダウンロード処理ができるか、それともControllerの方で何か処理ができるのか、試しています。
パスはローカル環境下では「C:ディレクトリ/ファイル名」ですが、本番環境では「http://IPアドレス/ディレクトリ/ファイル名」となります

-- クライアント側 $.ajax({ url: actionUrl, type: "GET", data: postData, cashe: false }).done(function (data) { alert(data); //window.location.href = data; }) -- サーバー側(上記Ajaxの行き先Controller) public string GetFile(Model m) { // パス取得処理 return path; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2017/06/02 07:04

現在実装しているソースコードもご提示ください。特に「ファイルへのフルパスを取得」あたりがキーになってきてるように思います。
f_horizon

2017/06/02 07:20

情報が足りずに申し訳ありません。追加しましたのでご参考ください。
退会済みユーザー

退会済みユーザー

2017/06/02 08:16

質問者さんの先のスレッド https://teratail.com/questions/53219 が放置・放棄状態ですが、最後まできちんと対応いただけるでしょうか?
f_horizon

2017/06/02 08:45

長い間悩んでいるうちに埋もれさせてしまっていましたね、すみません。そちらは締めておきますね。
guest

回答2

0

ベストアンサー

サーバーにある既存のファイルをダウンロードするなら、Controller のアクションメソッドで FilePathResult を返すオーバーロードの Controller.File メソッドを使うことをお勧めします。

Controller.File メソッド (String, String, String)
https://msdn.microsoft.com/ja-jp/library/dd492593(v=vs.118).aspx

その方向でやってみて、不明点があれば質問してください。

なお、js で行うというのは考えない方がよさそうです。

----- 2017/6/5 15:26 追記 -----

2017/06/05 14:50 の私のコメントで「return File(path, "text/plain", "TestFileName"); というのはちょっと問題がありそうな気がしますので、老婆心かもしれませんが、注意事項を回答欄に書いておきます」と書きましたが、それを以下に書いておきます。

ブラウザによって、応答ヘッダーの Content-Disposition: attachment; filename= で指定するファイル名の拡張子と、Content-Type: で指定する MIME Type のどちらでファイルの種類を判断するかが異なります。

なので、Content-Type と Content-Disposition の両方を正しく設定してやる必要があります。

それを設定するのが File メソッドの第 2, 3 引数です。

質問者さんのコードのように、

public ActionResult DownLoadTest(string path) { return File(path, "text/plain", "TestFileName"); }

としたとすると、応答ヘッダの Content-Disposition と Content-Type は以下のようになるはずです。

Content-Type: text/plain Content-Disposition: attachment; filename=TestFileName

Content-Type の方はダウンロードするファイルがホントにテキストファイルならそれでもいいですが、例えば .jpg ですと image/jpeg のようにしないとダメです。(ブラウザによっては、Content-Type の指定通り拡張子を書き換えてしまうものがあります)

Content-Disposition に設定するファイル名 TestFileName の方は拡張子まで指定するようにしてください。(テキストファイルなら TestFileName.txt、.jpg ファイルなら TestFileName.jpg というように)

投稿2017/06/02 07:40

編集2017/06/05 06:26
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

f_horizon

2017/06/05 05:17

以下書いておりますが、FilePathResultを使い無事にダウンロードできました。ありがとうございました。
退会済みユーザー

退会済みユーザー

2017/06/05 05:50

return File(path, "text/plain", "TestFileName"); というのはちょっと問題がありそうな気がしますので、老婆心かもしれませんが、注意事項を回答欄に書いておきます。
f_horizon

2017/06/06 01:03

ありがとうございます、その辺りも注意しながらやりたいと思います。
guest

0

パスだけではなく、中身もサーバー側で渡してあげないといけないかと思います。
必要ならヘッダを適切に処理してください。

C#

1public FileContentResult Foo() 2{ 3 return new FileContentResult(File.ReadAllBytes(Server.MapPath("~/abc/def.text")), "text/plain"); 4} 5

投稿2017/06/02 07:11

x_x

総合スコア13749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

f_horizon

2017/06/02 07:37

早速ご回答ありがとうございます。 取り急ぎご報告ですが、試したところ「物理パスでなく仮想パスを指定してください」との例外メッセージが出ています。引き続きFileContentResult周りを調べながらトライしてみます。
退会済みユーザー

退会済みユーザー

2017/06/03 02:09 編集

Controller.File メソッドに 6 種類のオーバーロードがあって、引数によって FileContentResult、FileStreamResult、FilePathResult という異なるオブジェクトを返します。 Controller.File メソッド https://msdn.microsoft.com/ja-jp/library/system.web.mvc.controller.file(v=vs.118).aspx なので、アクションメソッドからは、 return File(適切にオーバーロードを使うための引数); とするのがよさそうです。 また、FileContentResult、FileStreamResult、FilePathResult は、ファイルデータの型が、バイト列 or Stream or 既存のファイル・・・のいずれかによって使い分けます。 ~/abc/def.text に既存のファイルがあってそれをダウンロードするなら、それをわざわざバイト列にして FileContentResult を使う必要はなく、FilePathResult を使うべきだと思います。
f_horizon

2017/06/05 05:15 編集

ご回答ありがとうございます、FilePathResultを使い以下の方法で実現することができました。 クライアント側はajaxではなく、jsのcreateElement()でaタグ生成 -> パスを以下のコントローラーに飛ばすようにしました。 -- public ActionResult DownLoadTest(string path) { return File(path, "text/plain", "TestFileName"); } --
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問