【问题标题】:How do I Redirect to another Action/Controller in MVC3 from a VOID method?如何从 VOID 方法重定向到 MVC3 中的另一个动作/控制器?
【发布时间】:2011-11-13 05:48:05
【问题描述】:

我有一个返回 void 的控制器方法,因为它正在构建 Excel 报告供用户下载。我们正在使用的 Excel 3rd 方库正在写入响应本身。该方法看起来像这样:

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

如果用户不符合获取报告的特定凭据,则有多项安全检查会引发异常。我想重定向到不同的页面并传递一些有关异常的信息,但我不知道如何在 MVC3 中执行此操作....

有什么想法吗?

【问题讨论】:

    标签: asp.net-mvc model-view-controller asp.net-mvc-3


    【解决方案1】:

    您可以使用以下代码

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

    但是你看过FilePathResultFileStreamResult 吗?

    【讨论】:

      【解决方案2】:

      不要让第 3 部分库直接写入响应获取内容,而是使用常规 ActionResult 并在错误时返回 File(...) 实际文件或 RedirectToAction(...)(或 RedirectToRoute(...))。如果您的第 3 方库只能写入 Response,您可能需要使用一些技巧来捕获它的输出。

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

      【讨论】:

        【解决方案3】:

        您可以返回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 });    
              }
        
        }
        

        不确定它是否有效,没有测试过。

        【讨论】:

          【解决方案4】:

          另一种方法是使用异常过滤器:

          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"
                  //    //..
                  //};
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多