C# 异步控制器操作出错时重定向用户

C# 异步控制器操作出错时重定向用户,c#,asp.net-mvc,wcf,asynchronous,task,C#,Asp.net Mvc,Wcf,Asynchronous,Task,我有一个ASP.NET MVC 4web应用程序,它通过WCF服务从数据源检索数据 我已将大多数控制器设置为异步,并将后续方法设置为基于任务 不过我遇到了一个问题。如果我的代码中发生异常,正在加载的页面将继续加载,并在最后超时,同时显示IIS错误页面 我设置了一个友好的错误消息,可以很好地执行sync操作,但不能执行async操作。即使在不同级别发生异常,该操作仍会继续运行。我尝试将AsyncTimeout属性应用于控制器操作,但没有成功,页面只是长时间保持加载 有没有办法在我的代码中处理这个问

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

我已将大多数控制器设置为
异步
,并将后续方法设置为基于
任务

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

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

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

方法#1 在Web.config中将customErrors设置为On或RemoteOnly

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

如果您想执行控制器级别的操作,Dave A建议的
HandleError
非常完美。但要在全局级别应用HandleError属性,必须使用例外过滤器

您还可以将
HandleError
属性注册为全局错误处理程序,从而为整个应用程序应用该属性。要注册全局错误处理程序,请在
App_Start
文件夹中打开
FilterConfig.cs
文件以查找
RegisterGlobalFilters
方法。 默认情况下,ASP.NET MVC模板已将全局
HandleErrorAttribute
注册到应用程序的
GlobalFilterCollection
。在这里,您还可以将自己的自定义筛选器添加到全局筛选器集合,如:

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

  filters.Add(new HandleErrorAttribute()); //by default added
}
详情请参阅:

或者您可以使用
应用程序错误
(不推荐)捕获异常并重定向到所需操作,如:

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");
    }
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
  filters.Add(new HandleErrorAttribute
  {
    ExceptionType = typeof(System.TimeoutException),
    View = "TimeoutExceptionView"
  });

  filters.Add(new HandleErrorAttribute()); //by default added
}
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");
    }
}