ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.net5 core Razor 进阶之三:异常和日志处理

2021-05-23 11:32:29  阅读:127  来源: 互联网

标签:core 进阶 Razor public context using 日志 异常 logger


异常和日志是软件开发中不可或缺的一部分,总是成对出现,

程序运行过程中出现了异常,就需要用日志将此异常信息记录下来,为后续 debug 做参考。

在.NET5 Core Razor 中,日志和异常的处理比较简单,我们只需要做一些配置和少许编码就可以了,具体步骤如下。

注:

.NET5 Core自带的日志处理接口可以将日志信息输出到控制台、事件管理器等终端上,

但目前还不支持输出到文件,这里我们使用第三方包 Serilog.Extensions.Logging.File 来实现。

----------------------------------------------------------------------

第1步:引用 Serilog.Extensions.Logging.File 包并配置使用环境 。

具体参考这篇文章:https://www.cnblogs.com/pfm33/p/14336356.html

 

第2步:扑捉异常信息并调用相应的 Logger 方法写日志文件。

代码一般是这样的(还是以之前的学生成绩管理为例):

    public class ScoreMngModel : PageModel
    {
        private ILogger<ScoreMngModel> _logger; //定义日志对象
        private readonly ScoreContext _context;

        //在构造函数中做依赖注入
        public ScoreMngModel(ILogger<ScoreMngModel> logger, ScoreContext context)
        {
            _logger = logger; //注入日志实例
            _context = context; //注入 AuthDbContext 实例
        }

        public void OnGet()
        {
            try
            {
                _context.Database.ExecuteSqlRaw("UPDATE t_student SET class_name={0} WHERE stu_id={1}", "五(1)班", 1);
                //使用日志对象 _logger 的 LogInformation() 方法将信息写入日志文件
                _logger.LogInformation("UPDATE t_student SET class_name={0} WHERE stu_id={1}", "五(1)班", 1);
                
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message); //使用日志对象 _logger 的 LogError() 方法将异常信息写入日志文件
            }
        }

        // 其他代码......   

    }

运行后会在解决方案的根目录下生成对应的日志文件,如下:

除了 try-catch 这种方式外,还可以以  【Filter】 或 【中间件】 的方式来处理异常和记录日志 ,其区别是:

1. try-catch 方式需要在每个方法中使用 try {} catch {} 语句将代码包起来,工作量很大,不便于集中维护。

2. Filter 方式只需要实现相关的接口并做配置就可以了,非常适合捕获发生在操作中的异常,但 xxx.cshtml 中的异常无法捕获 。

3. 中间件 方式最灵活,其代码更简洁,后期维护也更方便,这是推荐的方式。

下面我们分别实现第2种和第3种方式。

 

一、Filter 方式的步骤如下:

第1步:在解决方案根目录中新建一个 Filters 的文件夹用来存放相关的类文件。

第2步:在 Filters 的文件夹下新增一个自定义 Filter 类 CustomExceptionFilter ,实现 IExceptionFilter 接口,如下:

代码如下:

namespace AuthManagement.Filters
{
    public class CustomExceptionFilter : IExceptionFilter
    {
        private ILogger<CustomExceptionFilter> _logger; //定义日志处理对象
        public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
        {
            _logger = logger; //在构造函数中注入日志处理实例
        }

        // 实现 IExceptionFilter 接口的 Onexception() 方法
        public void OnException(ExceptionContext context)
        {
            //使用日志对象 _logger 的 LogError() 方法将异常信息写入日志文件
            _logger.LogError(context.Exception, context.Exception.Message); 
        }
    }
}

第3步:在 Startup.cs 的 ConfigureServices() 方法中配置 Filter,代码如下:

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddScoped<CustomExceptionFilter>(); //将自定义的 ExceptionFilter 注入到容器
     
    //......          
}

删除 Logs 文件夹下之前产生的日志文件,在 .cs 文件中抛出一个 Exception , 如下:

public void OnGet()
{ 
    throw new Exception("test exception ....");
}

编译并运行程序,可以看到 Logs 文件夹下新增了一个日志文件:

 

二、中间件 方式的步骤如下:

第1步:在解决方案下新增一个文件夹 Middlewares

第2步:在该文件夹下新增一个 ExceptionMiddleware.cs 的中间件

代码如下:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AuthManagement.Middlewares
{
    // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class ExceptionMiddleware
    {
        private ILogger<ExceptionMiddleware> _logger; //定义日志处理对象
        private readonly RequestDelegate _next;

        public ExceptionMiddleware(ILogger<ExceptionMiddleware> logger,RequestDelegate next)
        {
            _logger = logger; //在构造函数中注入日志处理对象的实例
            _next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception ex) // 用 try-catch 来捕获异常。
            {
                _logger.LogError(ex, "##异常来源:{0}", httpContext.Request.Path); //调用日志处理对象的实例记录日志
            }
        }
    }


    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class ExceptionMiddlewareExtensions
    {
        public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ExceptionMiddleware>();
        }
    }
}

ExceptionMiddlewareExtensions 是新增中间件时自动生成的扩展方法类,用于异常中间件的启用,所以不需要在 Startup.cs 中做设置。

测试:

在 xxx.cshtml 文件中抛出异常:

@page
@model AuthManagement.Pages.Auth.ScoreMngModel
@using AuthManagement.DbUtil.Entity2;
@{
    throw new Exception("test ()()()$$$$$$$$$$$$$");
}

或者在 xxx.cshtml.cs 文件中抛出异常:

public void OnGet()
{  
    throw new Exception("test()()()77777......");
}

编译后运行程序,都可以在 /Logs 文件夹下看到生成的日志文件,如下:

这里虽然将异常记录到了日志文件中,实际项目中还需要做一下完善,

比如根据不同的异常类型跳转到一个自定义的错误页面。

 

标签:core,进阶,Razor,public,context,using,日志,异常,logger
来源: https://www.cnblogs.com/pfm33/p/14800283.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有