ABP core 重写默认过滤器 实现自定义 errorcode

针对自定义statscode的需求,我们需要重写ABP框架的两个默认过滤器

1,授权过滤器

    /// <summary>
    /// 权限验证过滤器
    /// </summary>
    public class AuthorizationFilter : IAsyncAuthorizationFilter, ITransientDependency
    {
        /// <summary>
        /// 
        /// </summary>
        public ILogger Logger { get; set; }

        private readonly IAuthorizationHelper _authorizationHelper;
        private readonly IErrorInfoBuilder _errorInfoBuilder;
        private readonly IEventBus _eventBus;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="authorizationHelper"></param>
        /// <param name="errorInfoBuilder"></param>
        /// <param name="eventBus"></param>
        public AuthorizationFilter(
            IAuthorizationHelper authorizationHelper,
            IErrorInfoBuilder errorInfoBuilder,
            IEventBus eventBus)
        {
            _authorizationHelper = authorizationHelper;
            _errorInfoBuilder = errorInfoBuilder;
            _eventBus = eventBus;
            Logger = NullLogger.Instance;
        }

        /// <summary>
        /// 权限验证
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            // Allow Anonymous skips all authorization
            if (context.Filters.Any(item => item is IAllowAnonymousFilter))
            {
                return;
            }

            if (!context.ActionDescriptor.IsControllerAction())
            {
                return;
            }

            //TODO: Avoid using try/catch, use conditional checking
            try
            {
                await _authorizationHelper.AuthorizeAsync(
                    context.ActionDescriptor.GetMethodInfo(),
                    context.ActionDescriptor.GetMethodInfo().DeclaringType
                );
            }
            catch (AbpAuthorizationException ex)
            {
                Logger.Warn(ex.ToString(), ex);

                _eventBus.Trigger(this, new AbpHandledExceptionData(ex));

                if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
                {
                    var er = _errorInfoBuilder.BuildForException(ex);
                     // 使用结果包装器的code作为自定义状态编码
                    er.Code = context.HttpContext.User.Identity.IsAuthenticated
                           ? (int)System.Net.HttpStatusCode.Forbidden
                           : (int)System.Net.HttpStatusCode.Unauthorized;
                    //将response状态码统一返回为200
                    context.Result = new ObjectResult(new AjaxResponse(er, true))
                    {
                        StatusCode = (int)System.Net.HttpStatusCode.OK
                    };
                }
                else
                {
                    context.Result = new ChallengeResult();
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString(), ex);

                _eventBus.Trigger(this, new AbpHandledExceptionData(ex));

                if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
                {
                    var er = _errorInfoBuilder.BuildForException(ex);
                    er.Code = (int)System.Net.HttpStatusCode.InternalServerError;
                    context.Result = new ObjectResult(new AjaxResponse(er))
                    {
                        StatusCode = (int)System.Net.HttpStatusCode.OK
                    };
                }
                else
                {
                    context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.InternalServerError);
                }
            }
        }
    }
View Code

2,异常过滤器

    /// <summary>
    /// 
    /// </summary>
    public class ExceptionFilter : IExceptionFilter, ITransientDependency
    {
        /// <summary>
        /// 
        /// </summary>
        public ILogger Logger { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public IEventBus EventBus { get; set; }

        private readonly IErrorInfoBuilder _errorInfoBuilder;
        private readonly IAbpAspNetCoreConfiguration _configuration;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="errorInfoBuilder"></param>
        /// <param name="configuration"></param>
        public ExceptionFilter(IErrorInfoBuilder errorInfoBuilder, IAbpAspNetCoreConfiguration configuration)
        {
            _errorInfoBuilder = errorInfoBuilder;
            _configuration = configuration;

            Logger = NullLogger.Instance;
            EventBus = NullEventBus.Instance;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            if (!context.ActionDescriptor.IsControllerAction())
            {
                return;
            }

            var wrapResultAttribute =
                ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(
                    context.ActionDescriptor.GetMethodInfo(),
                    _configuration.DefaultWrapResultAttribute
                );

            if (wrapResultAttribute.LogError)
            {
                LogHelper.LogException(Logger, context.Exception);
            }

            if (wrapResultAttribute.WrapOnError)
            {
                HandleAndWrapException(context);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        private void HandleAndWrapException(ExceptionContext context)
        {
            if (!ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
            {
                return;
            }

            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
            var errorInfo = _errorInfoBuilder.BuildForException(context.Exception);
            errorInfo.Code = GetStatusCode(context,errorInfo);
            context.Result = new ObjectResult(
                new AjaxResponse(
                    errorInfo,
                    context.Exception is AbpAuthorizationException
                )
            );

            EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));

            context.Exception = null; //Handled!
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="errorInfo"></param>
        /// <returns></returns>
        protected virtual int GetStatusCode(ExceptionContext context, ErrorInfo errorInfo)
        {
            if (context.Exception is AbpAuthorizationException)
            {
                return context.HttpContext.User.Identity.IsAuthenticated
                    ? (int)HttpStatusCode.Forbidden
                    : (int)HttpStatusCode.Unauthorized;
            }

            if (context.Exception is AbpValidationException)
            {
                return (int)HttpStatusCode.BadRequest;
            }

            if (context.Exception is EntityNotFoundException)
            {
                return (int)HttpStatusCode.NotFound;
            }

            if(context.Exception is UserFriendlyException)
            {
                return errorInfo.Code;
            }

            return (int)HttpStatusCode.InternalServerError;
        }
    }
View Code

3,在statup文件中注册重写的过滤器

// MVC
            services.AddMvc(
                options =>
                {
                    options.Filters.Add(new CorsAuthorizationFilterFactory(_defaultCorsPolicyName));
                    options.Filters.AddService(typeof(AuthorizationFilter), order: 0);
                    options.Filters.AddService(typeof(ExceptionFilter), order: 2);
                }
            );
View Code

注意代码中的的数字,测试发现如果不加入手动排序,ioc容器会把重写的过滤器置于次要地位,过滤器会不起作用

4,在ioc容器中注册这两个过滤器,我偷懒就都写在statup中了

            // Configure Abp and Dependency Injection
            return services.AddAbp<MarketManageWebHostModule>(
                options =>
                {
                    options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                );

                    options.IocManager.Register<IExceptionFilter, ExceptionFilter>(Abp.Dependency.DependencyLifeStyle.Transient);
                    options.IocManager.Register<IAsyncAuthorizationFilter, AuthorizationFilter>(Abp.Dependency.DependencyLifeStyle.Transient);
                }
            );
View Code

 

转载于:https://www.cnblogs.com/rokeyyan/p/9016256.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值