I have an ASP.NET MVC 4 web application that retrieves data from a data source via WCF services.
我有一个ASP.NET MVC 4 Web应用程序,它通过WCF服务从数据源检索数据。
I have set up most of controllers to be Async
and subsequent methods to be Task
based.
我已经将大多数控制器设置为Async,后续方法是基于任务的。
I have encountered a problem though. If an exception occurs in my code, the page being loaded just continues to load and in the end times-out with the IIS error page showing.
我遇到了一个问题。如果我的代码中发生异常,则正在加载的页面将继续加载,并在最后超时显示IIS错误页面。
I have a friendly error message set up and works fine for sync
actions but not async
ones. The action just keeps running even though an exception may have occurred at a different level. I tried applying the AsyncTimeout
attribute to the controller action but no luck, page just keeps loading for a long period of time.
我有一个友好的错误消息设置,适用于同步操作但不是异步操作。即使可能在不同级别发生异常,操作也会继续运行。我尝试将AsyncTimeout属性应用于控制器操作但没有运气,页面只是长时间保持加载。
Any ideas how I could handle this in my code, preferably at a global type level and direct the user to an error page when an issue occurs with an async
controller action?
任何想法如何在我的代码中处理这个问题,最好是在全局类型级别,并在异步控制器操作出现问题时将用户引导到错误页面?
2 个解决方案
#1
4
Approach #1
Set customErrors to On or RemoteOnly in Web.config
在Web.config中将customErrors设置为On或RemoteOnly
<system.web>
<customErrors mode="On" />
</system.web>
Use HandleErrorAttribute with custom error view
将HandleErrorAttribute与自定义错误视图一起使用
[AsyncTimeout(1000)]
[HandleError(ExceptionType=typeof(System.TimeoutException), View="Timeout")]
public async Task<ActionResult> AsyncActionResultReport()
{
Approach #2
Override the OnException Method of your Async Controller, or use a custom Exception Attribute
覆盖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);
}
#2
2
If you want to do controller level, the HandleError
as suggested by Dave A is perfect. But for applying HandleError Attribute at Global Level you have to use ExceptionFilter.
如果你想做控制器级别,Dave A建议的HandleError是完美的。但是要在全局级别应用HandleError属性,您必须使用ExceptionFilter。
You can also apply the HandleError
Attribute for the entire application by registering it as a global error handler. For registering a global error handler, open the FilterConfig.cs
file with in App_Start
folder to find the RegisterGlobalFilters
method. By default, ASP.NET MVC template has already registered a global HandleErrorAttribute
to the GlobalFilterCollection
for your application. Here you can also add your own custom filter to the global filter collection as well like :
您还可以通过将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
}
For details refer:
详情请参考:
OR
Alternatively you can use Application_Error
(NOT Recommended) to catch exception & redirect to required action like:
或者,您可以使用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");
}
}
#1
4
Approach #1
Set customErrors to On or RemoteOnly in Web.config
在Web.config中将customErrors设置为On或RemoteOnly
<system.web>
<customErrors mode="On" />
</system.web>
Use HandleErrorAttribute with custom error view
将HandleErrorAttribute与自定义错误视图一起使用
[AsyncTimeout(1000)]
[HandleError(ExceptionType=typeof(System.TimeoutException), View="Timeout")]
public async Task<ActionResult> AsyncActionResultReport()
{
Approach #2
Override the OnException Method of your Async Controller, or use a custom Exception Attribute
覆盖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);
}
#2
2
If you want to do controller level, the HandleError
as suggested by Dave A is perfect. But for applying HandleError Attribute at Global Level you have to use ExceptionFilter.
如果你想做控制器级别,Dave A建议的HandleError是完美的。但是要在全局级别应用HandleError属性,您必须使用ExceptionFilter。
You can also apply the HandleError
Attribute for the entire application by registering it as a global error handler. For registering a global error handler, open the FilterConfig.cs
file with in App_Start
folder to find the RegisterGlobalFilters
method. By default, ASP.NET MVC template has already registered a global HandleErrorAttribute
to the GlobalFilterCollection
for your application. Here you can also add your own custom filter to the global filter collection as well like :
您还可以通过将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
}
For details refer:
详情请参考:
OR
Alternatively you can use Application_Error
(NOT Recommended) to catch exception & redirect to required action like:
或者,您可以使用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");
}
}