我有asp.net核心应用程序。 configure方法的实现将用户重定向到"错误"有异常的页面(在非开发环境中)
但是只有在控制器内部发生异常时才有效。如果异常发生在控制器之外,例如在我的自定义中间件中,则用户不会被重定向到错误页面。
如何将用户重定向到"错误"如果中间件中存在异常,则为页面。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseSession();
app.UseMyMiddleware();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
更新1
我在上面的代码更新了初始帖子中缺少的以下两行。
app.UseSession();
app.UseMyMiddleware();
此外,我发现为什么app.UseExceptionHandler
无法重定向到错误页面
当我的中间件代码中存在异常时,app.UseExceptionHandler("\Home\Error")
会按预期重定向到\Home\Error
;但由于这是一个新请求,我的中间件再次执行并再次抛出异常
因此,要解决此问题,我将中间件更改为仅执行if context.Request.Path != "/Home/Error"
我不确定这是解决这个问题的正确方法,但是它的工作原理。
public class MyMiddleWare
{
private readonly RequestDelegate _next;
private readonly IDomainService _domainService;
public MyMiddleWare(RequestDelegate next, IDomainService domain)
{
_next = next;
_domainService = domain;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path != "/Home/Error")
{
if (context.User.Identity.IsAuthenticated && !context.Session.HasKey(SessionKeys.USERINFO))
{
// this method may throw exception if domain service is down
var userInfo = await _domainService.GetUserInformation(context.User.Name).ConfigureAwait(false);
context.Session.SetUserInfo(userInfo);
}
}
await _next(context);
}
}
public static class MyMiddleWareExtensions
{
public static IApplicationBuilder UseMyMiddleWare(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleWare>();
}
}
答案 0 :(得分:14)
您可以用来处理异常UseExceptionHandler()
,将此代码放入您的代码中
Startup.cs
。
UseExceptionHandler可用于全局处理异常。您可以获取异常对象的所有详细信息,如Stack Trace,Inner异常等。然后你可以在屏幕上显示它们。 Here
此处您可以阅读有关此诊断中间件的更多信息,并了解如何使用IExceptionFilter
以及创建自己的自定义异常处理程序。
app.UseExceptionHandler(
options =>
{
options.Run(
async context =>
{
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.ContentType = "text/html";
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace}";
await context.Response.WriteAsync(err).ConfigureAwait(false);
}
});
}
);
您还必须删除UseDeveloperExceptionPage()
之类的默认设置,如果您使用它,它始终显示默认错误页面。
if (env.IsDevelopment())
{
//This line should be deleted
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
答案 1 :(得分:6)
您应该编写自己的中间件来处理自定义异常处理。并确保将其添加到中间件堆栈的开头(如果可能的话首先),因为在堆栈中“早期”的中间件中发生的异常将无法处理。
示例:
dd <- t(apply(df, 1, function(x) table(factor(x, levels=1:max(df)))))
colSums(dd) >= 4
1 2 3 4 5 6 7
FALSE TRUE FALSE TRUE FALSE FALSE FALSE