web-dev-qa-db-ja.com

ASP.NET MVC 4FileResult-エラー

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に設定されている場合、どうすればブラウザに通信問題が発生したことを確認できますか?

10
Ian Vink

メソッドの戻り値の型を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");
    }
}
23
Adam Modlin

エラーが発生したことを「ブラウザに伝達」したい場合、特にリクエストが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の結果を返すことは完全に許容されます。

7
haim770

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);
}
7
ataravati

前提条件を処理するための別の回避策は、ダウンロードプロセスを2つの段階に分割することです。 1つ目は、ajax/postメソッドとして実行されるサーバー側メソッドの前提条件を確認することです。

次に、これらの前提条件が満たされている場合は、ダウンロード要求を開始できます(たとえば、onSuccessコールバックで、達成を示す戻り値がチェックされます)。この場合、(サーバー側で)上記の投稿で説明した方法で潜在的な例外を処理します。

2
Bronek