Как отследить нарушение ограничения БД и выдать исключение UserFriendlyException? - PullRequest
0 голосов
/ 29 июня 2018

У меня 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 голосов
/ 30 июня 2018

Я пытался перехватить его в переопределении метода 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");
    }
}

В качестве альтернативы, переопределите SaveChanges и SaveChangesAsync в вашем DbContext:

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");
    }
}
0 голосов
/ 29 июня 2018

Используете ли вы ASP.NET Core?

Потому что в документации ABP: (https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions) Этот документ предназначен для ASP.NET MVC и веб-API. Если вы заинтересованы в ASP.NET Core, обратитесь к документации по ASP.NET Core.

Я должен использовать TempData и ViewBag для отображения ошибки пользователю в модальном режиме ...

...