我有一个 ASP.NET MVC 4 Web应用程序,它通过WCF服务从数据源检索数据。
我已将大多数控制器设置为Async
,后续方法基于Task
。
我遇到了一个问题。如果我的代码中发生异常,则正在加载的页面将继续加载,并在最后超时显示IIS错误页面。
我设置了一个友好的错误消息,适用于sync
个动作,但不适用于async
个动作。即使异常可能发生在不同的级别,操作也会继续运行。我尝试将AsyncTimeout
属性应用于控制器操作,但没有运气,页面只是长时间加载。
我在代码中如何处理此问题的任何想法,最好是在全局类型级别,并在async
控制器操作出现问题时将用户引导到错误页面?
答案 0 :(得分:4)
在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()
{
覆盖Async Controller的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);
}
答案 1 :(得分:2)
如果你想做控制器级别,Dave A建议的HandleError
是完美的。但是,要在全局级别应用 HandleError属性,您必须使用 ExceptionFilter 。
您还可以通过将整个应用程序注册为全局错误处理程序来应用HandleError
属性。要注册全局错误处理程序,请在FilterConfig.cs
文件夹中打开App_Start
文件以查找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
}
详情请参阅:
或强>
或者您可以使用Application_Error
(非推荐)来捕捉异常&amp;重定向到所需的操作,如:
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");
}
}