首页 > 编程语言 >ASP .NET Core Api使用过滤器

ASP .NET Core Api使用过滤器

时间:2022-12-03 00:22:25浏览次数:31  
标签:Core ASP ActionArguments Api context var using logger public

Asp.net webapi 为我们提供的 ActionFilterAttribute 拦截器,通过 重写 OnActionExecuting,来 拦截action的请求消息,当执行OnActionExecuting完成以后才真正进入请求的action中,action运行完后又把控制权给了 OnActionExecuted,这个管道机制可以使我们用它来轻松实现 权限认证、日志记录 ,跨域以及很多需要对全局或者部分请求做手脚的的功能。
大概的流程如下:

asp.net core 里面的过滤器有这么多:

  • IActionFilter
  • IResourceFilter
  • IResultFilter
  • IAuthorizationFilter
  • IPageFilter
  • IExceptionFilter
  • ActionFilterAttribute

获取Api请求相关信息

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Text;
using System.Text.Json;

namespace WebApplication1
{
    //[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]//方法级别
    public class ApiFilter : ActionFilterAttribute
    {

        private string ActionArguments { get; set; }
        private readonly ILogger<ApiFilter> _logger;
        private readonly IServiceProvider _serviceProvider;
        public ApiFilter(ILogger<ApiFilter> logger, IServiceProvider serviceProvider)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 执行方法体之后,返回result前
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {

            var request = context?.HttpContext?.Request;

            //请求地址
            string url = request.Host + request.Path + request.QueryString;

            var descriptor = (ControllerActionDescriptor)context.ActionDescriptor;
            //获取控制器名称
            var controllerName = descriptor.ControllerName;
            //获取action名称
            var actionName = descriptor.ActionName;
            //获取request参数
            var requestArguments = ActionArguments;
            //请求方式
            string method = request.Method;
            //请求Header
            var headrs = request.Headers;
            //context.HttpContext.Request.Form

            //Response
            var Response = context?.HttpContext?.Response;
            var result = context.Result;
            if (result is JsonResult json)
            {
                var x = json.Value;
                var status = json.StatusCode;
                var content = JsonSerializer.Serialize(x);
            }
            if (result is ViewResult view)
            {
                var status = view.StatusCode;
                var x = view.ViewData;
                var name = view.ViewName;
            }
            if (result is ObjectResult ob)
            {
                var x = ob.Value;
                var status = ob.StatusCode;
                var content = JsonSerializer.Serialize(x);
            }

            base.OnActionExecuted(context);

        }

        /// <summary>
        /// 执行方法体之前
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                if (context.ActionArguments != null && context.ActionArguments.Count > 0)
                {
                    ActionArguments = JsonSerializer.Serialize(context.ActionArguments);
                }
                else
                {
                    ActionArguments = string.Empty;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.StackTrace);
            }

            base.OnActionExecuting(context);
        }

        /// <summary>
        /// 返回result之前
        /// </summary>
        /// <param name="context"></param>
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            base.OnResultExecuting(context);
        }

        /// <summary>
        /// 返回result之后
        /// </summary>
        /// <param name="context"></param>
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            base.OnResultExecuted(context);
        }
    }
}

Exception记录日志

using Microsoft.AspNetCore.Mvc.Filters;
using System.Text.Json;

namespace WebApplication1
{
    public class ExceptionFilter : ActionFilterAttribute
    {
        private string ActionArguments { get; set; }
        private readonly ILogger<ApiFilter> _logger;
        private readonly IServiceProvider _serviceProvider;
        public ExceptionFilter(ILogger<ApiFilter> logger, IServiceProvider serviceProvider)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 执行方法体之后,返回result前
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.Exception != null)
            {
                LoggerError(context, context.Exception);
            }

            base.OnActionExecuted(context);
        }

        /// <summary>
        /// 执行方法体之前
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                if (context.ActionArguments != null && context.ActionArguments.Count > 0)
                {
                    ActionArguments = JsonSerializer.Serialize(context.ActionArguments);
                }
                else
                {
                    ActionArguments = string.Empty;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.StackTrace);
            }

            base.OnActionExecuting(context);
        }


        private void LoggerError(ActionExecutedContext context, Exception exception)
        {
            try
            {
                string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
                string method = context.HttpContext.Request.Method;
                string message = $"\n" + $"地址:{url} \n " +
                $"方式:{method} \n " +
                $"参数:{ActionArguments}\n " +
                $"错误描述:{context.Exception.Message}\n " +
                $"错误堆栈:{context.Exception.StackTrace}\n ";
                if (exception.InnerException != null)
                {
                    message += "\n InnerException异常Message:" + exception.InnerException.Message;
                    message += "\n InnerException异常StackTrace:" + exception.InnerException.StackTrace;
                }
                _logger.LogError(message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.StackTrace);
            }
        }
    }
}

添加过滤器

Program.cs添加Filter

builder.Services.AddControllers(options =>
{
    //options.Filters.Add(new ApiFilter(null,null));
    options.Filters.Add<ApiFilter>();
});

标签:Core,ASP,ActionArguments,Api,context,var,using,logger,public
From: https://www.cnblogs.com/RainFate/p/16946047.html

相关文章

  • .Net Core 静态类获取注入服务
    由于静态类中无法使用有参构造函数,从而不能使用常规的方式(构造函数获取)获取服务,我们可以采取通过IApplicationBuilder获取1.首先创建一个静态类usingMicrosoft.......
  • ASP.NET Web API Demo OwinSelfHost 自宿主 Swagger Swashbuckle 在线文档
    新建WebAPI工程 选Empty,勾选WebAPI,不要选择WebAPI,那样会把MVC勾上,这里不需要MVCWebAPI工程属性 XML文件用于生成在线文档  新建Windows服务作为WebAPI的......
  • 使用自签名证书在Docker中部署Asp.Net Core(Abp)项目
    一编写Dockerfile文件FROMmcr.microsoft.com/dotnet/aspnet:6.0COPY//appWORKDIR/appEXPOSE80ENTRYPOINT["dotnet","Acme.BookStore.Web.dll"]#设置时区......
  • .Net Core SignalR 初体验
    前言Asp.NetSignalR已经出来很久了,但是一直没有静下心来好好看看。昨天花了几个小时的时间看了下。首先借鉴了官方文档,如何搭建一个SignalR的Demo。参考文章:ht......
  • ASP.NET Core SignalR .NET 客户端
    项目2022/11/2913个参与者反馈通过ASP.NETCoreSignalR.NET客户端库可以从.NET应用与SignalR中心进行通信。查看或下载示例代码(如何下载)本文......
  • Jenkins API 返回403错误
    Jenkins 版本:2.346.1接口调用报403,研究了一下发现了是jenkins的CSRF机制导致的,但是由于公司所用的jenkins版本较高,默认不支持关闭CSRF,所以需要在jenkins控制台中手动关......
  • ASP.NET 向SQLSERVER中批量插入数据
    usingSystem.Data;usingSystem.Diagnostics;usingSystem.Data.SqlClient;stringconnectionString="DataSource=HG-J3EJJ9LSW5PY;InitialCatalog=Test......
  • C#中数据的批量插入和更新_Asp.net
    对于海量数据的插入和更新,ADO.NET确实不如JDBC做到好,JDBC有统一的模型来进行批操作.使用起来非常方便: PreparedStatementps=conn.prepareStatement("insertorupd......
  • ASP.NET中如何调用存储过程
     用ASP.NET与SQLSERVER可是缘份最好了,稍大的程序一般第一先考虑的是SQLSERVER,只是一些很考虑经济的才使用ACCESS等了。用SQLSERVER,为了使数据库的效率更好,一般都会才取......
  • asp教程:ASP开发中存储过程应用详解
    ASP开发中存储过程应用详解|调用,参数,存储,数据库,输出,编译,mycomm,输入,userid,代码ASP与存储过程(StoredProcedures)的文章不少,但是我怀疑作者们是否真正实践过。......