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