Как перенаправить на другое действие / контроллер в MVC3 из метода VOID? - PullRequest
7 голосов
/ 08 сентября 2011

У меня есть метод контроллера, который возвращает пустоту, потому что он создает отчет Excel для загрузки пользователем. Используемая нами сторонняя библиотека Excel записывает сам ответ. Метод выглядит примерно так:

[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 ....

Есть идеи?

Ответы [ 4 ]

8 голосов
/ 08 сентября 2011

Вы могли бы сделать

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

Но взглянули ли вы на FilePathResult или FileStreamResult ?

2 голосов
/ 08 сентября 2011

Вы можете вернуть 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 });    
      }

}

Не уверен, что это работает, не проверял его.

2 голосов
/ 08 сентября 2011

Вместо того, чтобы позволить 3-й части библиотеки писать в ответ напрямую, получайте содержимое, используйте регулярное ActionResult и возвращайте File(...) для фактического файла или RedirectToAction(...) (или RedirectToRoute(...)) при ошибке. Если ваша сторонняя библиотека может писать только в 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  });
  }
}
0 голосов
/ 09 сентября 2011

Другой подход будет использовать фильтр исключений:

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"
        //    //..
        //};
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...