ASP.NET MVC 4 FileResult – 出错

我在控制器上有一个简单的Action,它返回一个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"); } } 

如果你想“与浏览器通信”有错误,标准的“HTTP方式”是返回状态代码500,特别是如果你的请求是使用Ajax调用的,这样你就可以优雅地处理exception。

我建议在没有找到提供的id报告时抛出Exception

 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中的最佳方法,因为这通常是HandleErrorfilter(默认情况下应用)的角色,可以轻松配置为重定向或呈现某些Viewexception详细信息(同时仍保持HTTP状态500)。

假设未能获取报告确实被视为exception,则这是真的。 如果不是(例如,如果我们希望某些报告没有要转储的可用文件),则显式返回Redirect/View结果是完全可以接受的。

FileResult类inheritance自ActionResult 。 因此,您可以像这样定义您的Action:

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

处理先决条件的另一个解决方法是将下载过程分为两个阶段。 首先是检查服务器端方法中的前提条件,该方法作为ajax / post方法执行。

然后,如果满足这些前提条件,您可以开始下载请求(例如,在onSuccess回调中检查指示履行的返回值),其中(在服务器端)您将以上述post中描述的方式处理潜在的exception。