【问题标题】:Redirect user when error occurs in async controller action异步控制器操作中发生错误时重定向用户
【发布时间】:2014-07-27 03:09:48
【问题描述】:

我有一个 ASP.NET MVC 4 Web 应用程序,它通过 WCF 服务从数据源检索数据。

我已将大多数控制器设置为Async,后续方法设置为基于Task

我遇到了一个问题。如果我的代码中发生异常,则正在加载的页面将继续加载并最终超时并显示 IIS 错误页面。

我设置了一条友好的错误消息,并且对于 sync 操作可以正常工作,但对于 async 操作则不行。即使异常可能发生在不同的级别,该操作仍会继续运行。我尝试将AsyncTimeout 属性应用于控制器操作,但没有成功,页面只是长时间加载。

有什么想法可以在我的代码中处理这个问题,最好是在全局类型级别,并在 async 控制器操作出现问题时将用户引导到错误页面?

【问题讨论】:

    标签: c# asp.net-mvc wcf asynchronous task


    【解决方案1】:

    方法#1

    在 Web.config 中将 customErrors 设置为 On 或 RemoteOnly

    <system.web>
        <customErrors mode="On" />
    </system.web>
    

    在自定义错误视图中使用 HandleErrorAttribute

    [AsyncTimeout(1000)]
    [HandleError(ExceptionType=typeof(System.TimeoutException), View="Timeout")]
    public async Task<ActionResult> AsyncActionResultReport()
    {
    

    方法#2

    覆盖异步控制器的 OnException 方法,或使用自定义异常属性

    public override void OnException(ExceptionContext filterContext)
    {
        if(filterContext.Exception is TimeoutException && filterContext.Controller is AsyncController)
        {
            filterContext.HttpContext.Response.StatusCode = 200;
            filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary {
                        { "Controller", "Home" },
                        { "Action", "TimeoutRedirect" }
            filterContext.ExceptionHandled = true;
        }
    
        base.OnException(filterContext);
    }
    

    【讨论】:

      【解决方案2】:

      如果你想做控制器级别,Dave A 建议的HandleError 是完美的。但是要在全局级别应用 HandleError 属性,您必须使用 ExceptionFilter

      您还可以通过将HandleError 属性注册为全局错误处理程序,将其应用于整个应用程序。要注册全局错误处理程序,请打开 App_Start 文件夹中的 FilterConfig.cs 文件以找到 RegisterGlobalFilters 方法。 默认情况下,ASP.NET MVC 模板已经为您的应用程序注册了一个全局HandleErrorAttributeGlobalFilterCollection。在这里,您还可以将自己的自定义过滤器添加到全局过滤器集合中,例如:

      public static void RegisterGlobalFilters(GlobalFilterCollection filters)
      {
        filters.Add(new HandleErrorAttribute
        {
          ExceptionType = typeof(System.TimeoutException),
          View = "TimeoutExceptionView"
        });
      
        filters.Add(new HandleErrorAttribute()); //by default added
      }
      

      详情参考:

      http://www.dotnet-tricks.com/Tutorial/mvc/19D9140313-Exception-or-Error-Handling-and-Logging-in-MVC4.html

      或者您可以使用Application_Error(不推荐)捕获异常并重定向到所需的操作,例如:

      protected void Application_Error(object sender, EventArgs e)
      {
          Exception exception = Server.GetLastError();
          System.Diagnostics.Debug.WriteLine(exception);
          if (exc.GetType() == typeof(TimeoutException)
          {
            Response.Redirect("/Home/ErrorView");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 1970-01-01
        • 2013-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多