异常过滤器中的重定向

7

我正在使用ASP.NET Core。我的其中一个控制器调用服务,该服务会抛出各种异常。我想在异常过滤器(而非中间件)中处理它们。

public class MyHandlerAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext c)
    {
      if (c.Exception is FooException) {
          // redirect with arguments to here
      } 
      else if (c.Exception is FooException) {
          // redirect with arguments to there
      }
      else {
          // redirect to main error action without arguments, as 500
      }
      base.OnException(c);
    }
}

与操作过滤器不同,异常过滤器无法访问Controller,因此我无法执行c.Result = controller.RedirectTo...()。那么,我该如何重定向到我的错误操作?
2个回答

15

HttpContextExceptionContext 上公开,因此您可以将其用于重定向。

context.HttpContext.Response.Redirect("...");

还有一个Result属性,但我不确定在筛选器执行后是否会被解释。尽管如此,值得一试:

context.Result = new RedirectResult("...");

如果它能工作,那么它也应该适用于 RedirectToActionResultRedirectToRouteResult


第二个不起作用。如果您还设置了context.Exception = null;,则第一个可以工作。但是这种类型的重定向不允许我指定参数 - 这可能吗? - grokky
3
第二个选项也可行。但您还应该设置 context.ExceptionHandled = true; - juunas
@juunas 如果我这样做,它只会呈现一个空白页面... 奇怪! - grokky
总之:第一种形式可以工作,但无法传递参数,第二种形式接受参数,但由于错误而无法工作。 - grokky

0
如果您想要重定向到控制器的操作并传递一个或多个值,您需要使用RouteValueDictionary。这适用于从ExceptionFilterAttribute传递数据到控制器方法的重定向和传递数据。
在以下示例中,我将重定向到错误控制器的Test_Error操作,并传递一个整数值(id)。这是使用.NET Core 2.2进行测试的。 自定义属性
public class Custom_ExceptionAttribute : ExceptionFilterAttribute, IExceptionFilter
{
    var routeData = new RouteValueDictionary(new {
                      controller = "Error",
                      action = "Test_Error",
                      id = 1,
                   });
    filterContext.ExceptionHandled = true;
    filterContext.Result = new RedirectToRouteResult(routeData);
    filterContext.Result.ExecuteResultAsync(filterContext);
}

控制器与动作

public class ErrorController : Controller
{
     public IActionResult Test_Error(int id)
     {
         //do whatever
     }
}

当然可以将异常、控制器和抛出异常的操作传递给控制器的操作,并从那里处理它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接