乐趣区

关于c#:如何在-ASPNET-Core-中实现全局异常拦截

异样是一种运行时谬误,当异样没有失去适当的解决,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 ASP.Net Core MVC 中实现全局异样解决,我会用一些 样例代码 和 截图 来阐明这些概念。

全局异样解决

其实在 ASP.Net Core MVC 框架中曾经有了全局异样解决的机制,你能够在一个中心化的中央应用 全局异样解决中间件 来进行异样拦挡,如果不必这种中心化形式的话,你就只能在 Controller 或者 Action 作用域上独自解决,这会导致异样解决代码零散在我的项目各处,不好保护也特地麻烦,不是吗?

第二种解决 全局异样 的做法就是应用 exception filter,在本篇中,我筹备跟大家聊一聊 全局异样解决中间件 UseExceptionHandler 办法来管控异样。

应用 UseExceptionHandler 扩大办法

UseExceptionHandler 扩大办法可能将 ExceptionHandler 中间件注册到 Asp.net Core 的 申请解决管道 中,而后在 IExceptionHandlerFeature 接口的实例中获取 异样对象,上面的代码片段展现了如何应用 UseExceptionHandler 办法来截获全局异样。


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseExceptionHandler(builder =>
             {
                 builder.Run(async context =>
                {context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.ContentType = "application/json";

                    var exception = context.Features.Get<IExceptionHandlerFeature>();
                    if (exception != null)
                    {var error = new ErrorMessage()
                        {
                            Stacktrace = exception.Error.StackTrace,
                            Message = exception.Error.Message
                        };
                        var errObj = JsonConvert.SerializeObject(error);

                        await context.Response.WriteAsync(errObj).ConfigureAwait(false);
                    }
                });
             }
         );


            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

上面是代码中援用的 ErrorMessage 类的定义。


    public class ErrorMessage
    {public string Message { get; set;}
        public string Stacktrace {get; set;}
    }

配置 全局异样中间件

大家都晓得,ASP.Net Core MVC 我的项目中都会有一个 Startup.cs 文件,能够在 Configure 办法下配置 全局异样拦挡中间件 代码,如下所示:


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {if (env.IsDevelopment())
            {app.UseDeveloperExceptionPage();
            }
            else
            {app.UseExceptionHandler("/Error");
            }
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template:
                    "{controller=Home}/{action=Index}/{id?}");
            });
        }

能够着重看一下下面的 app.UseExceptionHandler("/Error"); ,这里的 UseExceptionHandler 实现了 pipeline 注册,一旦应用程序呈现了未解决异样,那么会主动将 用户 导向 /Error 页面。

你能够用 UseStatusCodePagesWithReExecute 扩大办法给 pipeline 增加一些状态码页面,这是什么意思呢?其实也就是 http 500 导向 500 页面,http 404 导向 404 页面,上面的代码片段展现了批改后的 Configure 办法代码。


   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   {if (env.IsDevelopment())
            {app.UseDeveloperExceptionPage();
            }
            else
            {app.UseExceptionHandler("/Error");
                app.UseStatusCodePagesWithReExecute("/Error/NotFound/{0}");
            }
            
            //Other code
   }

应用 ErrorController

在 HomeController 下有一个专门处理错误的 action 办法,这里咱们不应用这个 action,你能够把它删掉,接下来我筹备定义一个专门的 ErrorController,外面蕴含了一个路由为 /Error 的 action 办法。


    public class ErrorController : Controller
    {[HttpGet("/Error")]
        public IActionResult Index()
        {IExceptionHandlerPathFeature iExceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

            if (iExceptionHandlerFeature != null)
            {
                string path = iExceptionHandlerFeature.Path;
                Exception exception = iExceptionHandlerFeature.Error;

                //Write code here to log the exception details
                return View("Error",iExceptionHandlerFeature);
            }                
            return View();}

        [HttpGet("/Error/NotFound/{statusCode}")]
        public IActionResult NotFound(int statusCode)
        {var iStatusCodeReExecuteFeature =HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
            return View("NotFound",iStatusCodeReExecuteFeature.OriginalPath);
        }
    }

你能够用 IExceptionHandlerPathFeature 来获取异样相干信息,也能够用 IStatusCodeReExecuteFeature 来获取 http 404 异样时过后的申请门路,对了,要想用上 IExceptionHandlerPathFeature IStatusCodeReExecuteFeature, 要记得在 nuget 上装置了 Microsoft.AspNetCore.Diagnostics 包,上面的代码展现了如何获取异样产生时刻的路由地址。


string route = iExceptionHandlerFeature.Path;

如果想获取异样的详细信息,能够应用如下语句。


var exception = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

一旦获取了这个路由地址和异样的详细信息,就能够将它记录到你的日志文件中,可供后续仔细分析。

应用 View 展现错误信息

能够创立一个 View 来展现呈现的错误信息,上面时 Error ViewPage 的具体代码。


@model Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature
@{ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="row">
    <div class="text-danger">
        <h3>Error: @Model.Error.Message</h3>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <p>@Model.Error.StackTrace</p>
        <p>@Model.Error.InnerException</p>
    </div>
</div>

上面是 NotFound 页面的 代码


@model string
@{ViewData["Title"] = "NotFound";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
    <h1 class="text-danger">
    Error: The requested URL @Model was not found!</h1>
<hr />

当初能够把程序跑起来了,你会看到如下的错误信息。

如果你尝试关上一个不存在的页面,会主动跳转到 ErrorController.NotFound 所包装的 404 形容信息。

ASP.NET Core 中内置了 全局异样解决,你能够利用这项技术在一个集中化的中央去截获你应用程序中的所有异样信息,当然你也能够基于环境的不同采取不必的异样解决措施,比如说:开发环境,测试环境,生产环境 等等。

译文链接:https://www.infoworld.com/art…

更多高质量干货:参见我的 GitHub: dotnetfly

退出移动版