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

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

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

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

C#

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

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

Q&A

解決済

1回答

7118閲覧

【ASP.NET MVC】アップロードしたファイルの確認ページの実装について

yukibeatles

総合スコア12

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

C#

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

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

0グッド

0クリップ

投稿2020/06/13 04:39

編集2020/06/13 04:49

実現したいこと

ASP.NET MVCにて、
以下の様なWebページ遷移・動作、またはそれと同等な機能を実装としたいと考えております。

<ファイルをアップロードするページ>
・ファイル選択ダイアログより、サーバにアップロードするファイルを選択し、
”確認画面へ”ボタン押下で<アップロードするファイルを確認するページ>へ遷移。

<アップロードするファイルを確認するページ>
・前ページで選択されたファイルを一覧表示し、
”アップロード”ボタンが押下されると、サーバにファイルをアップロードし、
<アップロード完了ページ>へ遷移。
”戻る”ボタンが押下されると、サーバにファイルをアップロードせずに、
<ファイルをアップロードするページ>へ遷移。

<アップロード完了ページ>
。"アップロード完了しました"の表示。

発生している問題・エラーメッセージ

<アップロードするファイルを確認するページ>から、”アップロード”ボタンを押下すると、以下のエラーが表示されます。

System.ObjectDisposedException: 閉じているファイルにはアクセスできません。

該当のソースコード

使用するモデルは以下の様に定義しています。

C#

1public class UploadData { 2 public IList<HttpPostedFileBase> UploadFilesForUploading { get; set; } 3}

コントローラは以下の様に定義しました。

<ファイルをアップロードするページ>から<アップロードするファイルを確認するページ>へのPOST時のアクションメソッド

C#

1[HttpPost] 2public ActionResult Upload(UploadData uploadData) { 3 if (ModelState.IsValid) 4         //入力データをセッションに格納 5 Session["tempUploadData"] = uploadData; 6 7 return View("Details", uploadData); 8}

<アップロードするファイルを確認するページ>から<アップロード完了ページ>へのPOST時のアクションメソッド

C#

1[HttpPost] 2public ActionResult Details(string process) { 3 //セッションから入力データを取得 4 var uploadData = new UploadData(); 5 uploadData = Session["tempUploadData"] as UploadData; 6 7     //ファイルアップロード 8 foreach (var uploadFile in uploadData.UploadFilesForUploading) { 9 uploadFile.SaveAs(uploadFileForServer); //ここでエラー 10 } 11 12 return RedirectToAction("Complete"); 13}

試したこと

HTTPがステートレスなプロトコルであることから、今回のように3ページを渡る場合は、
SessionまたはTempDataを利用する必要があるものと考え、上記のような設計としましたが、
上記エラーが発生することから、Sessionはアップロードファイル自身を含むことはできないものと認識しました。

その為、<ファイルをアップロードするページ>から<アップロードするファイルを確認するページ>へのPOST時のアクションメソッド内に、
サーバへのファイルアップロード処理を実装し、
<アップロードするファイルを確認するページ>から<アップロード完了ページ>へのPOST時のアクションメソッド内に、
”アップロード”ボタン押下時は、何もせず、
”戻る”ボタン押下時に、サーバへアップロードしたファイルを削除する、
という処理を実装したところ、正しく動作しました。

しかし、サーバへのファイルアップロード処理を行い、<アップロードするファイルを確認するページ>を表示しているときに、
ユーザ側でブラウザを閉じてしまった場合、サーバにアップロードしたファイルが削除されず残ってしまいます。
この同期をとる為に、<アップロードするファイルを確認するページ>のセッションのタイムアウト時間を設定しておき、
<ファイルをアップロードするページ>に、現時刻から設定したセッションタイムアウト時間より以前にアップロードされたファイルがあれば削除する、といった処理を追加することも視野に入れておりますが、処理を極力シンプルにしたいと考えております。

###開発環境
●環境
・統合環境:Visual Studio 2019

●プロジェクト
・使用言語:C#(.NET Framework 4.6.1)
・種別:ASP.NET MVC 5 Webアプリケーション

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/06/13 04:42

開発環境(Visual Studio のバージョン、.NET Framework なのか Core なのかとそのバージョンなど)を質問欄を編集して追記してください。
guest

回答1

0

ベストアンサー

System.ObjectDisposedException: 閉じているファイルにはアクセスできません。

その時点ではファイルは消去されてしまっているからであろうと思います。

.NET 3.5, 4 の場合 POST されたデータ(ファイルを含む)は 80KB を超えるとメモリではなくてディスクに一時保存されます。詳しくは以下の記事を見てください。

アップロードされたファイルの一時保存先
http://surferonwww.info/BlogEngine/post/2011/08/01/Temporary-store-of-uploaded-file.aspx

ディスクに一時保存されたファイルは、サーバーが応答を返した後、消去されてしまうようです。

上の記事にも書いてありますが、以前「FileUpload を Session に保存しておいて、後で Save しようとしたが、ファイルサイズが大きいと失敗する。そのサイズの限度が大体 80KB」という報告があって、その原因究明に悩んだことがありました。

上限が 80KB ということから気が付いたのですが、ディスクに一時保存されたファイルが消去されてしまうことが原因でした。

それは Web Forms アプリの話でしたが、MVC でも同じことだと思います。

Session にファイルへの参照を保持してもディスクに一時保存されたファイル本体は消されてしまうので(80KB を超える場合)、消されてしまった後の次回の要求で何かファイル操作するというのは無理だと思います。他のシナリオ・手段を考えることをお勧めします。

投稿2020/06/13 05:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yukibeatles

2020/06/13 05:33

いつも詳細のご回答ありがとうございます。 そういった理由でSessionには保存されず、呼び出せないのですね。 私の考える代替シナリオとして、 ”試したこと”の後半部分の手段を考えておりますが、 他に何かシンプルな案はありますでしょうか。 質問の本論とずれてしまい申し訳ございませんが、ご教示頂ければ幸いです。
退会済みユーザー

退会済みユーザー

2020/06/13 07:26 編集

> 私の考える代替シナリオとして、”試したこと”の後半部分の手段を考えておりますが、他に何かシンプルな案はありますでしょうか。 そのあたりは質問者さんの事情もあるでしょうから、それを知らない第三者が案を出すのは難しいですが、思い付きレベルでよければ、例えば、 (1) 削除しないでそのままにしておく。 (2) ディスクスペースを圧迫するなどの理由で (1) では困るのであれば、 > ”アップロード”ボタン押下時は、何もせず、 というところで「何もせず」ではなくて、その操作で DB などにファイル名を保存するとかしておいて、後で定期的にまとめてファイル名が保存されてないファイルを削除する機能を作る。 ・・・ぐらいでしょうか。ユーザーに途中でブラウザを閉じられてしまったら、その後できることは限られてきて、Session などを使って判断という質問者さんの案は難しそうな気がします。
yukibeatles

2020/06/14 23:10

ご提案ありがとうございます。 DBで管理する方法も良さそうですね。 他にもサーバで常駐プログラムを配置する等、色々案がありそうですので、 考えられる方法を洗い出した上、最も良い方法を考えたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問