首页 > 解决方案 > Automapper 配置文件的 UserFriendlyException

问题描述

我遇到了问题。我有在实体中定义的业务规则,在实体中验证此规则时,如果业务规则被破坏,我会抛出 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;
}

在 Automapper 配置文件中,我基本上有默认规则

创建地图();

当它发生时,我在客户端没有 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 配置文件的异常。请帮我解决这个问题。

标签: aspnetboilerplate

解决方案


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

所以我所做的就是解开 UserFriendlyException。

我继承了 AbpExceptionFilter 并覆盖了 HandleAndWrapException 方法。

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。


推荐阅读