オフィス狛 技術部のJoeです。
最近、ASP.NET MVCで開発されたWebシステムの改修プロジェクトをお手伝いしたのですが、ASP.NET MVCでの開発が初めてだったので、色々と戸惑いが多かったです。
その中でも、あるエラーについての対処方法をご紹介したいと思います。
今回のプロジェクトでは、ControllerからViewを表示したり、別のアクションを起こす場合は、主に下記のActionResultオブジェクトを使っていました。
① 呼び出し元のViewを表示する
return View();
② 指定したViewを表示する
return View("~/Views/Test/index.cshtml");
③ 指定したControllerのアクションを実行する
return RedirectToAction(MethodName.Index, ControllerName.Test);
ところが、ファイルをダウンロードした後に上記のActionResultオブジェクトを使用すると、Exceptionが発生してしまいました。
[ C#(Response.WriteFileメソッドを使用してサーバ上のExcelファイルをダウンロード) ]
// Excelファイルをダウンロード var DownloadFile = Server.MapPath("~/Reports/Download.xlsx"); long offset = 0; long size = new FileInfo(DownloadFile).Length; Response.Clear(); Response.ContentEncoding = Encoding.GetEncoding("UTF-8"); Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; // これはExcel Response.AppendHeader("content-disposition", "attachment; filename=" + Server.UrlEncode("ダウンロード.xlsx")); Response.WriteFile(DownloadFile, offset, size); Response.End(); // 呼び出し元のViewを表示する(①のパターン) return View();
[ エラー内容 ]
HTTP ヘッダーの送信後にサーバーでヘッダーを追加できません。
②でも同じエラーになります。
実は今回、CSRF対策としてView側で「Html.AntiForgeryToken」ヘルパーを呼び出していました。
ファイルをダウンロードしているので、「Response.End()」の時点でクライアントにHTTPヘッダーが送信されています。
「return View(…)」でViewを返した際に、View側で「Html.AntiForgeryToken」ヘルパーがCookieを設定しようとして、エラーになってしまいました。
では③「RedirectToAction」を試してみると
[ エラー内容 ]
HTTP ヘッダーを送信後はリダイレクトできません。
こちらはエラーのとおり、リダイレクトができないようです。
【対処方法1】何も返さない
何も返さなければいいということで、以下に修正してExceptionを回避できました。
return new EmptyResult();
ちなみに以下でも同じ動きです。MVCが判断して「return new EmptyResult();」を返してくれます。
return null;
【対処方法2】ダウンロードするファイルを返す
こちらは「return File」でファイルを返します。(「Response.WriteFileメソッド」を使用しません)
なんだかスッキリしてますし、ダウンロード後に何か処理が無ければこちらのほうが良いですね。
[ C# ]
var DownloadFile = Server.MapPath("~/Reports/ManuallyRecord.xlsx"); var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; // Excel return File(DownloadFile, contentType, Server.UrlEncode("ダウンロード.xlsx"));
ActionResultオブジェクトだけでもいろいろなパターンがあって、まだまだ覚えることがたくさんありそうです。
ASP.net , C#
0 件のコメント:
コメントを投稿