2011-09-08 21 views
7

Tengo un método de controlador que devuelve un vacío porque está creando un informe de Excel para que el usuario lo descargue. La biblioteca de terceros de Excel que estamos utilizando está escribiendo en la respuesta en sí. El método es como la siguiente:¿Cómo puedo redireccionar a otra acción/controlador en MVC3 desde un método VOID?

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

Hay varios controles de seguridad en el lugar que generen excepciones si el usuario no cumple con ciertas credenciales para ir a buscar el informe. Quiero redireccionar a una página diferente y pasar algo de información sobre la excepción, pero no puedo encontrar la manera de hacerlo en MVC3 ...

¿Alguna idea?

Respuesta

2

En lugar de dejar que la tercera parte de la biblioteca de escritura a la respuesta de obtener directamente el contenido ActionResult uso regular y volver File(...) para el archivo real o RedirectToAction(...) (o RedirectToRoute(...)) en caso de error. Si su biblioteca de terceros solo puede escribir en Response, es posible que necesite utilizar algunos trucos para capturar su resultado.

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

Usted podría hacer un

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

Pero has echado un vistazo a la FilePathResult o FileStreamResult?

+0

Gracias importante. Funcionó para mí – Mohan

2

Usted puede devolver un 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 });  
     } 

} 

No estoy seguro si funciona, no lo he probado.

0

Otro enfoque sería utilizar un filtro de excepción:

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