How do I Redirect to another Action/Controller in

2020-07-09 09:03发布

I have a controller method that returns a void because it is building an Excel report for the user to download. The Excel 3rd party library we're using is writing to the response itself. The method looks something like this:

[HttpGet]
public void GetExcel(int id)
{
  try
  {
    var report = _reportService.GetReport(id);
    var table = _reportService.GetReportTable(id);
    var excelReport = new ExcelReport(table, report.Name);
    excelReport.DownloadReport(System.Web.HttpContext.Current.Response);
  }
  catch (Exception ex)
  {
    // This is wrong, of course, because I'm not returning an ActionResult
    Response.RedirectToRoute("/Report/Error/", new { exceptionType = ex.GetType().Name });
  }
}

There are several security checks in place that throw exceptions if the user doesn't meet certain credentials for fetching the report. I want to redirect to a different page and pass along some information about the exception, but I can't figure out how to do this in MVC3....

Any ideas?

4条回答
Root(大扎)
2楼-- · 2020-07-09 09:28

Another approach would be using an exception filter:

public class MyExceptionFilter : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        var routeValues = new RouteValueDictionary()
        {
            { "controller", "Error" },
            { "action", "Report" }
        };

        filterContext.Result = new RedirectToRouteResult(routeValues);
        filterContext.ExceptionHandled = true;

        // Or I can skip the redirection and render a whole new view

        //filterContext.Result = new ViewResult()
        //{
        //    ViewName = "Error"
        //    //..
        //};
    }
}
查看更多
放我归山
3楼-- · 2020-07-09 09:35

Instead of letting the 3rd part library write to the response directly get the content use regular ActionResult and return File(...) for the actual file or RedirectToAction(...) (or RedirectToRoute(...)) on error. If your 3rd party library can only write to Response you may need to use some tricks to capture it's output.

[HttpGet]
public ActionResult GetExcel(int id)
{
  try
  {
    var report = _reportService.GetReport(id);
    var table = _reportService.GetReportTable(id);
    var excelReport = new ExcelReport(table, report.Name);
    var content = excelReport.MakeReport(System.Web.HttpContext.Current.Response);
    return File(content, "application/xls", "something.xls");
  }
  catch (Exception ex)
  {
    RedirectToRoute("/Report/Error/", new { exceptionType = ex.GetType().Name  });
  }
}
查看更多
劫难
4楼-- · 2020-07-09 09:41

You could do a

Response.Redirect(Url.Action("Error", "Report", new { exceptionType = ex.GetType().Name });

But have you taken a look at the FilePathResult or FileStreamResult ?

查看更多
女痞
5楼-- · 2020-07-09 09:49

You can return an EmptyActionResult:

[HttpGet]
public ActionResult GetExcel(int id)
{ 
      try
      {
        var report = _reportService.GetReport(id);
        var table = _reportService.GetReportTable(id);
        var excelReport = new ExcelReport(table, report.Name);
        excelReport.DownloadReport(System.Web.HttpContext.Current.Response);

        return new EmptyResult();
      }
      catch (Exception ex)
      {
        return RedirectToAction("Error", "Report", rnew { exceptionType = ex.GetType().Name });    
      }

}

Not sure if it works, haven't tested it.

查看更多
登录 后发表回答