ASP.NET MVC 4 FileResult - 出错

时间:2013-12-02 18:53:54

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我在控制器上有一个简单的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时,如何与浏览器进行通信表示存在问题?

4 个答案:

答案 0 :(得分:21)

我会将您的方法的返回类型更改为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");
    }
}

答案 1 :(得分:7)

FileResult类继承自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);
}

答案 2 :(得分:7)

如果您想“与浏览器通信”发生错误,标准的“HTTP方式”是返回状态代码500,尤其是在使用Ajax调用您的请求时,您可以优雅地处理异常。

我建议在找不到所提供的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过滤器(默认情况下应用)的角色,可以可以轻松配置为使用Exception详细信息重定向或呈现某些View(同时仍保持HTTP状态500)。

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

答案 3 :(得分:2)

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

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