如何捕获数据库约束违规并抛出 UserFriendlyException?

gvd*_*vdm 1 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

现在我想捕获此异常并重新抛出 aUserFriendlyException以向用户显示消息。我尝试在方法的重写中捕获它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");
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我尝试实现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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

调试时,我可以看到它到达了该throw new UserFriendlyException行,但没有任何反应(没有向用户显示任何消息),因此该throw new UserFriendlyException行似乎被隐藏/忽略。

我可以做什么来解决这个问题?

谢谢。

aar*_*ron 5

我尝试在方法的重写中捕获它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");
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,在 DbContext 中覆盖SaveChangesand :SaveChangesAsync

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.SaveChangesAsync(cancellationToken);
    }
    catch (DbUpdateException ex)
    {
        throw new UserFriendlyException("A message for the user");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我在“DbContext”中实现了替代方案,并且效果非常好。万分感谢 (2认同)