如何捕获数据库约束违规并引发UserFriendlyException?

时间:2018-06-29 14:30:00

标签: c# asp.net-core aspnetboilerplate

我以这种方式定义了CrudAppService

public class MyAppService : AsyncCrudAppService<MyEntity, MyDto, int, PagedAndSortedResultRequestDto, MyCreateDto, MyDto>, IMyAppService, ITransientDependency
{
    private readonly IRepository<MyEntity> _MyRepository;

    public MyAppService(IRepository<MyEntity> repository) : base(repository)
    {
        _MyRepository = repository;
    }
}

我还在实体MyEntity的字段上定义了唯一约束,因此,当我尝试创建多个具有相同字段值的实体时,它将中断并抛出DbUpdateException。很好。

现在,我想捕获此异常并重新抛出UserFriendlyException以向用户显示一条消息。我尝试在Create()方法的替代中捕获它,但没有被捕获。

public override Task<MyDto> Create(MyCreateDto input)
{
    try
    {
        return base.Create(input);
    }
    catch(Exception ex)
    {
        // Never gets here
        throw new UserFriendlyException("A message for the user");
    }
}

因此,我尝试实现IEventHandler<AbpHandledExceptionData>来过滤DbUpdateException并抛出UserFriendlyException

class MyExceptionHandler : IEventHandler<AbpHandledExceptionData>, ITransientDependency
{
    public MyExceptionHandler()
    {
    }

    public void HandleEvent(AbpHandledExceptionData eventData)
    {
        if (eventData.Exception is DbUpdateException dbUpdateEx) {
            throw new UserFriendlyException("A message for the user");
        }
    }
}

调试时,我可以看到它到达了throw new UserFriendlyException行,但是什么也没发生(没有消息显示给用户),因此throw new UserFriendlyException行似乎被隐藏/忽略了。

我该怎么做才能解决此问题?

谢谢。

2 个答案:

答案 0 :(得分:2)

  

我尝试使用Create()方法的替代方法来捕获它,但是没有被捕获。

您需要致电_unitOfWorkManager.Current.SaveChanges()

public override Task<MyDto> Create(MyCreateDto input)
{
    try
    {
        var dto = base.Create(input);
        _unitOfWorkManager.Current.SaveChanges();
        return dto;
    }
    catch (DbUpdateException ex)
    {
        throw new UserFriendlyException("A message for the user");
    }
}

或者,在您的DbContext中覆盖SaveChangesSaveChangesAsync

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbUpdateException ex)
    {
        throw new UserFriendlyException("A message for the user");
    }
}

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
    try
    {
        return await base.SaveChanges();
    }
    catch (DbUpdateException ex)
    {
        throw new UserFriendlyException("A message for the user");
    }
}

答案 1 :(得分:0)

您是否正在使用ASP.NET Core?

因为在ABP文档中:(https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions) 本文档适用于ASP.NET MVC和Web API。如果您对ASP.NET Core感兴趣,请参阅ASP.NET Core文档。

我必须使用TempData和ViewBag在模态下向用户显示错误...