PDFを返すコントローラーに簡単なアクションがあります。
正常に動作します。
public FileResult GetReport(string id)
{
byte[] fileBytes = _manager.GetReport(id);
string fileName = id+ ".pdf";
return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}
マネージャーがレポートの取得に失敗すると、null
または空のbyte[]
が返されます。
結果がFileResult
に設定されている場合、どうすればブラウザに通信問題が発生したことを確認できますか?
メソッドの戻り値の型をActionResultに変更します。
public ActionResult GetReport(string id)
{
byte[] fileBytes = _manager.GetReport(id);
if (fileBytes != null && fileBytes.Any()){
string fileName = id+ ".pdf";
return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}
else {
//do whatever you want here
return RedirectToAction("GetReportError");
}
}
エラーが発生したことを「ブラウザに伝達」したい場合、特にリクエストがAjaxを使用して呼び出された場合、標準の「HTTP方法」はステータスコード500を返すことで、例外を適切に処理できます。
提供されたException
のレポートが見つからない場合は、単にid
をスローすることをお勧めします。
public FileResult GetReport(string id)
{
// could internally throw the Exception inside 'GetReport' method
byte[] fileBytes = _manager.GetReport(id);
// or...
if (fileBytes == null || !fileBytes.Any())
throw new Exception(String.Format("No report found with id {0}", id));
return File(fileBytes, MediaTypeNames.Application.Octet, fileName = id+ ".pdf");
}
エラーページに明示的にリダイレクトしたり、ViewResult
を返すことは、ASP.NET MVCでの最善のアプローチではありません。これは通常、HandleError
フィルター(デフォルトで適用される)の役割であるためです。一部のビューを例外の詳細とともにリダイレクトまたはレンダリングするように簡単に構成できます(HTTPステータス500を維持したまま)。
これは、レポートのフェッチの失敗が実際に例外と見なされると仮定すると、すべて当てはまります。そうでない場合(たとえば、一部のレポートにダンプできるファイルがないと予想される場合)、明示的にRedirect/View
の結果を返すことは完全に許容されます。
FileResult
クラスはActionResult
から継承します。したがって、アクションは次のように定義できます。
public ActionResult GetReport(string id)
{
byte[] fileBytes = _manager.GetReport(id);
string fileName = id + ".pdf";
if(fileBytes == null || fileBytes.Length == 0)
return View("Error");
return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}
前提条件を処理するための別の回避策は、ダウンロードプロセスを2つの段階に分割することです。 1つ目は、ajax/postメソッドとして実行されるサーバー側メソッドの前提条件を確認することです。
次に、これらの前提条件が満たされている場合は、ダウンロード要求を開始できます(たとえば、onSuccessコールバックで、達成を示す戻り値がチェックされます)。この場合、(サーバー側で)上記の投稿で説明した方法で潜在的な例外を処理します。