简体   繁体   English

处理asp.net核心中的异常?

[英]Handling exception in asp.net core?

I have asp.net core application. 我有asp.net核心应用程序。 The implementation of configure method redirects the user to "Error" page when there is an exception ( in non Development environment) 当存在异常时(在非开发环境中),configure方法的实现将用户重定向到“Error”页面

However it only works if the exception occurs inside controller. 但是,只有在控制器内发生异常时,它才有效。 If exception occurs outside of controller, for example in my custom middleware, then the user does not get redirected to error page. 如果异常发生在控制器之外,例如在我的自定义中间件中,则用户不会被重定向到错误页面。

How do i redirect user to "Error" page if there is an exception in the middleware. 如果中间件中存在异常,如何将用户重定向到“错误”页面。

     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?}");
        });
    }

Update 1 更新1
I updated code above with the following two lines that were missing in initial post. 我在上面的代码更新了初始帖子中缺少的以下两行。

        app.UseSession();
        app.UseMyMiddleware();

Also I found why app.UseExceptionHandler was not able to redirect to Error page. 另外我发现为什么app.UseExceptionHandler无法重定向到错误页面。
When there is an exception in my middleware code, app.UseExceptionHandler("\\Home\\Error") is redirecting to \\Home\\Error as expected; 当我的中间件代码中存在异常时, app.UseExceptionHandler("\\Home\\Error")将按预期重定向到\\Home\\Error ; but since that is a new request, my middleware was executing again and throwing exception again. 但由于这是一个新请求,我的中间件再次执行并再次抛出异常。
So to solve the issue i changed my middleware to execute only if context.Request.Path != "/Home/Error" 因此,为了解决这个问题,我改变了我的中间件,只有if context.Request.Path != "/Home/Error"时才执行

I am not sure if this is the correct way to solve this issue but its working. 我不确定这是解决这个问题的正确方法,但是它的工作原理。

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>();
    }
 }

You can use to handle exceptions UseExceptionHandler() , put this code in your Startup.cs . 您可以使用处理异常UseExceptionHandler() ,将此代码放在Startup.cs

UseExceptionHandler can be used to handle exceptions globally. UseExceptionHandler可用于全局处理异常。 You can get all the details of exception object like Stack Trace, Inner exception and others. 您可以获取异常对象的所有详细信息,如Stack Trace,Inner异常等。 And then you can show them on screen. 然后你可以在屏幕上显示它们。 Here 这里

Here You can read more about this diagnostic middleware and find how using IExceptionFilter and by creating your own custom exception handler. 在这里您可以阅读有关此诊断中间件的更多信息,并了解如何使用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);
                            }
                        });
                }
            );

You have to also delete default setting like UseDeveloperExceptionPage() , if you use it, it always show default error page. 您还必须删除默认设置,如UseDeveloperExceptionPage() ,如果您使用它,它始终显示默认错误页面。

   if (env.IsDevelopment())
        {
            //This line should be deleted
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

You should write your own middleware to handle custom exception handling. 您应该编写自己的中间件来处理自定义异常处理。 And make sure you add it towards the beginning (first if possible) of your middleware stack because exceptions that happen in middleware that is "earlier" in a stack will not be handled. 并确保将其添加到中间件堆栈的开头(如果可能的话首先),因为在堆栈中“早期”的中间件中发生的异常将不会被处理。

Example: 例:

public class CustomExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public CustomExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try 
        {
            await _next.Invoke(context);
        } 
        catch (Exception e) 
        {
            // Handle exception
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM