简体   繁体   English

ASP.NET MVC 4 FileResult - 出错

[英]ASP.NET MVC 4 FileResult - In error

I have a simple Action on a controller which returns a PDF. 我在控制器上有一个简单的Action,它返回一个PDF。

Works fine. 工作良好。

public FileResult GetReport(string id)
{
    byte[] fileBytes = _manager.GetReport(id);
    string fileName = id+ ".pdf";
    return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}

When the manager fails to get the report I get back null or an empty byte[] . 当管理器无法获得报告时,我得到null或空byte[]

How can I communicate to the browser that there was a problem, when the result is set to a FileResult ? 当结果设置为FileResult时,如何与浏览器通信存在问题?

I would change the return type of your method to ActionResult. 我会将您的方法的返回类型更改为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");
    }
}

The FileResult class inherits from ActionResult . FileResult类继承自ActionResult So, you can define your Action like this: 因此,您可以像这样定义您的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);
}

If you want to "communicate to the browser" that there was an error, the standard "HTTP way" is to return status code 500, especially if your request is invoked using Ajax, so that you can gracefully handle the exception. 如果你想“与浏览器通信”有错误,标准的“HTTP方式”是返回状态代码500,特别是如果你的请求是使用Ajax调用的,这样你就可以优雅地处理异常。

I would suggest to simply throw an Exception when no report found for the provided id : 我建议在找不到提供的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");
}

Explicitly redirecting to an error page or returning a ViewResult is not the best approach in ASP.NET MVC as this is usually the role of the HandleError filter (which is applied by default) that can be easily configured to either redirect or render some View with the Exception details (while still maintaining HTTP status 500). 显式重定向到错误页面或返回ViewResult不是ASP.NET MVC中的最佳方法,因为这通常是HandleError过滤器(默认情况下应用)的角色,可以轻松配置为重定向或呈现某些View异常详细信息(同时仍保持HTTP状态500)。

This is all true assuming that a failure to fetch a report is indeed considered an exception. 假设未能获取报告确实被视为异常,则这是真的。 If it's not (for example, if we expect some report to not have an available file to dump), explicitly returning a Redirect/View result is totally acceptable. 如果不是(例如,如果我们希望某些报告没有要转储的可用文件),则显式返回Redirect/View结果是完全可以接受的。

Another workaround for handling prerequisites is to split download process into two stages. 处理先决条件的另一种解决方法是将下载过程分为两个阶段。 First is to check preconditions in server side method which is executed as ajax/post method. 首先是检查服务器端方法中的前提条件,该方法作为ajax / post方法执行。

Then if these preconditions are fulfilled you can start download request (eg in onSuccess callback where it is checked the return value indicating fulfillment) in which (on server side) you will handle potential exceptions in a way as it was described in above posts. 然后,如果满足这些前提条件,您可以开始下载请求(例如,在onSuccess回调中检查指示履行的返回值),其中(在服务器端)您将以上述帖子中描述的方式处理潜在的异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM