ICode9

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

.NetCore中 Attributers、Filters以及中间件的使用

2022-08-11 15:31:52  阅读:148  来源: 互联网

标签:nameof WriteLine NetCore 中间件 Attributers return context Console public


Filters

Filters在.net core有一下几种:

  • AuthorizationFilter 认证过滤器
  • ResourceFilter 资源过滤器
  • ActionFilterAttribute 请求过滤器
  • ExceptionFilterAttribute 异常过滤器
  • ResultFilterAttribute 结果过滤器

执行顺序如下图:

各过滤器内方法执行流程如下:

AuthorizationFilter

认证过滤器的简单使用

    public class AuthorizationFilter : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            Console.WriteLine($"{nameof(AuthorizationFilter)}:{nameof(OnAuthorization)}");
            if (!Authorization(context.HttpContext)) return;
        }
        private bool Authorization(HttpContext context)
        {
            if (1 != 1)
            {
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                _ = context.Response.WriteAsJsonAsync("Unauthorized");
                return false;
            }
            return true;
        }
    }
builder.Services.AddControllers(t =>
{
    t.Filters.Add<AuthorizationFilter>();
});

ResourceFilter

ResourceFilter 的简单应用

public class ResourceFilter : IResourceFilter
    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine($"{nameof(ResourceFilter)}:{nameof(OnResourceExecuted)}");
        }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine($"{nameof(ResourceFilter)}:{nameof(OnResourceExecuting)}");

            //对请求信息进行处理
            context.HttpContext.Request.Headers.TryAdd("CORE_HEADER", "123");
                       //Encoding.UTF8.GetString(buffer)
            context.HttpContext.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(""));
        }
builder.Services.AddControllers(t =>
{
    t.Filters.Add<ResourceFilter>();
});

ActionFilter

public class ActionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"{nameof(ActionFilter)}:{nameof(OnActionExecuted)}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"{nameof(ActionFilter)}:{nameof(OnActionExecuting)}");
            //获得请求信息等
            var headers = context.HttpContext.Request.Headers;
        }

        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"{nameof(ActionFilter)}:{nameof(OnResultExecuted)}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"{nameof(ActionFilter)}:{nameof(OnResultExecuting)}");
            //对返回的action结果进行处理
        }

    }
builder.Services.AddControllers(t =>
{
    t.Filters.Add<ActionFilter>();
});

ResultFilter

使用ResultFilter对返回结果进行重组

public class ResultFilter : ResultFilterAttribute
    {
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"{nameof(ResultFilter)}:{nameof(OnResultExecuted)}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"{nameof(ResultFilter)}:{nameof(OnResultExecuted)}");
            //重写返回数据流
            //Encoding.UTF8.GetString(buffer)
            context.HttpContext.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(""));
        }
    }
builder.Services.AddControllers(t =>
{
    t.Filters.Add<ResultFilter>();
});

ExceptionFilter

ExceptionFilter捕获异常,并对其进行处理

 public class ExceptionFilter:ExceptionFilterAttribute
    {
        public override void OnException(ExceptionContext context)
        {
            Console.WriteLine($"{nameof(ExceptionFilter)}:{nameof(OnException)}");
  			context.HttpContext.Response.Body= new MemoryStream(Encoding.UTF8.GetBytes(""));
            base.OnException(context);
        }
    }

Attributers

特性(Attributers )根据其自身创建时的约束,AttributeUsage特性 [AttributeUsage(AttributeTargets.Property| AttributeTargets.Class)] 标识可以用在哪些地方。

定义一个特性,使其只可在类和方法上使用

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class IPAttribute : Attribute
    {

        private readonly string _ip;

        public string IP
        {
            get { return _ip; }
        }
        public IPAttribute(string ip)
        {
            _ip = ip;
        }
        public bool CheckIP(string ip)
        {
            return !string.IsNullOrEmpty(ip);
        }
    }

将特性防止在接口方法上

 [IPAttribute("127.0.0.1")]
        [HttpGet("GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

在访问时对其进行校验

 public class AuthorizationFilter : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            Console.WriteLine($"{nameof(AuthorizationFilter)}:{nameof(OnAuthorization)}");
            if (!Authorization(context.HttpContext)) return;
        }
        private bool Authorization(HttpContext context)
        {
            IPAttribute? authIP = context.GetEndpoint()?.Metadata?.GetMetadata<IPAttribute>();
            #region IP校验
            if (authIP != null && !CheckAttributeIP(authIP, context))
            {
                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                context.Response.WriteAsync("IP Unauthorized").GetAwaiter();
                return false;
            }
            #endregion IP校验
            return true;
        }
        private static bool CheckAttributeIP(IPAttribute authIPAttribute, HttpContext context)
        {
            //获得客户端IP
            string clientIP = context.Connection.RemoteIpAddress.ToString();
            if (context.Request.Headers.ContainsKey("X-Forwarded-For"))
                clientIP = context.Request.Headers["X-Forwarded-For"];
            if (string.IsNullOrEmpty(clientIP)) return false;
            return authIPAttribute.IP.Contains(clientIP);
            return false;
        }
    }

当访问IP不为127.0.0.1时,会返回401错误

Middleware

中间件是基于切面的一种组件

定义一个中间件,你可以在InvokeAsync中对context做任何操作

    public class RequestIPMiddleware
    {
        private readonly RequestDelegate _next;
        public RequestIPMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            Console.WriteLine("user IP:" + context.Connection?.RemoteIpAddress?.ToString());
            await _next.Invoke(context);
        }
    }

添加中间件

app.UseMiddleware<RequestIPMiddleware>();//添加中间件

标签:nameof,WriteLine,NetCore,中间件,Attributers,return,context,Console,public
来源: https://www.cnblogs.com/lostsea/p/16576169.html

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

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

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

ICode9版权所有