代码之家  ›  专栏  ›  技术社区  ›  grinay

自动应用程序配置文件的用户友好异常

  •  0
  • grinay  · 技术社区  · 7 年前

    我遇到了麻烦。我有在实体中定义的业务规则,而在实体中验证此规则时,如果业务规则被破坏,我将抛出UserFriendlyException。例子:

    private DateTime? _expireDate;
    
    public DateTime? ExpireDate {
        get => _expireDate;
        set {
            if (value.HasValue) {
                _expireDate = EnsureExpireDateRules (value.Value);
                PeriodInMonth = 0;
            }
        }
    }
    
    private DateTime EnsureExpireDateRules (DateTime dateTime) {
        dateTime = dateTime.GetDateZeroTime ();
    
        var currentUtcDateTime = DateTime.UtcNow.GetDateZeroTime ();
    
        if (dateTime <= currentUtcDateTime)
            throw new UserFriendlyException ("License date should be at least one day late than today.");
    
        return dateTime;
    }
    

    创建映射();

    当它发生时,我在客户端没有UserFriendlyException,相反,我有500个代码的普通异常(内部服务器错误)。 在日志系统中,我看到以下内容:

    AutoMapper.AutoMapperMappingException: Error mapping types.
    
    Mapping types:
    LicenseRequestInput -> LicenseRequest
    LicenseManager.LicenseManager.Dto.LicenseRequestInput -> LicenseManager.LicenseManager.Entities.LicenseRequest
    
    Type Map configuration:
    LicenseRequestInput -> LicenseRequest
    LicenseManager.LicenseManager.Dto.LicenseRequestInput -> LicenseManager.LicenseManager.Entities.LicenseRequest
    
    Destination Member:
    ExpireDate
     ---> Abp.UI.UserFriendlyException: License date should be at least one day late than today.
       at LicenseManager.LicenseManager.Entities.LicenseRequest.EnsureExpireDateRules(DateTime dateTime) in /Users/grinay/License management portal/src/LicenseManager.Core/LicenseManager/Entities/LicenseRequest.cs:line 56
    .....more...... 
    

    看起来ABP没有拦截来自Automap配置文件的异常。请帮助我解决这个问题。

    0 回复  |  直到 7 年前
        1
  •  0
  •   Alper Ebicoglu    7 年前

    问题是:

    自动映射器包装 UserFriendlyException AutoMapperMappingException . 因为外部异常不是 用户友好异常 阿布再也无法应付了!

    解决方案:

    投入 EnsureExpireDateRules() 在你的DTO里面( LicenseRequestInput

    更新:

    你想做的最好的做法是;

    protected set ,使构造函数受保护。您可以创建一个公共方法,用强制属性初始化您的实体。让你的经理来处理你的业务领域逻辑。

    public class MyEntity 
    {
        public DateTime? ExpireDate {get; protected set;}
    
        protected MyEntity()
        {
    
        }
    
        public MyEntity(mandatoryPropertiesToCreateYourEntity...)
        {
    
        }
    }
    

     public class MyEntityManager
        {
    
            public void SetExpireDate(MyEntity myEntity, DateTime? expireDate){
            {
                  if(myBusinessLogicIsOk) {
                      myEntity.ExpireDate = expireDate;
                  }
                  else
                  {
                      throw new Exception("Invalid expire date!");
                  }
            }
       }
    
        2
  •  0
  •   grinay    7 年前

    我为此扩展了AbpExceptionFilter。不确定这是否是好的做法,但我已经用它包装任务返回值。

    我继承了AbpExceptionFilter并重写了handleandwrappexception方法。

    protected override void HandleAndWrapException(ExceptionContext context, WrapResultAttribute wrapResultAttribute)
            {
      if (!ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
                {
                    return;
                }
    
                context.HttpContext.Response.StatusCode = GetStatusCode(context, wrapResultAttribute.WrapOnError);
    
                if (!wrapResultAttribute.WrapOnError)
                {
                    return;
                }
    
                if (context.Exception is AutoMapperMappingException && context.Exception.InnerException is UserFriendlyException)
                {
                    context.Exception = context.Exception.InnerException;;
                }
    
                context.Result = new ObjectResult(
                    new AjaxResponse(
                        _errorInfoBuilder.BuildForException(context.Exception),
                        context.Exception is AbpAuthorizationException
                    )
                );
    
                EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));
    
                context.Exception = null; //Handled!
    
            }
    

     public override void PreInitialize()
            {
    ...
                Configuration.ReplaceService<AbpExceptionFilter, CustomAbpExceptionFilter>();
    
    ...
            }
    

    现在它返回我的UserFriendlyException以防映射错误。

    推荐文章