Невозможно отловить DbUpdateConcurrencyException и выдать UserFriendlyException - PullRequest
0 голосов
/ 26 ноября 2018

Я использую ASP.NET Boilerplate с Code-First Entity Framework и MVC 5. Я хочу обрабатывать параллелизм.В методе Update я помещаю аннотацию данных Timestamp для поля RowVersion в моей сущности.

В менеджере моей сущности и в операции Update я пытаюсь поймать DbUpdateConcurrencyExceptionисключение и выбрасывание UserFriendlyException, но, поскольку UpdateAsync является асинхронным, я не знаю, где обрабатывать исключение.

Где следует обрабатывать это исключение, чтобы оно было удобным для пользователя и не отображало внутреннюю ошибку сервера?

public abstract class BaseFullAuditedEntity : FullAuditedEntity<Guid>
{
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

public class Branch : BaseFullAuditedEntity
{
    public string Name { get; set; }
}

Код менеджера:

public interface IBranchManager : IDomainService
{
    Task<Branch> Update(Branch branch, byte[] RowVersion);
}

public class BranchManager : DomainService, IBranchManager
{
    private IRepository<Branch, Guid> _branchRepository { get; }

    public async Task<Branch> Update(Branch branch, byte[] RowVersion)
    {
        try
        {
            return await _branchRepository.UpdateAsync(branch);
        }
        catch (DbUpdateConcurrencyException ex)
        {
            throw new UserFriendlyException("Update Concurrency Happened");
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

UpdateAsync(branch) только добавляет branch к контексту.

Inject IUnitOfWorkManager и await SaveChangesAsync():

try
{
    await _branchRepository.UpdateAsync(branch);
    await _unitOfWorkManager.Current.SaveChangesAsync(); // Add this
    return branch;
}
catch (DbUpdateConcurrencyException ex)
{
    throw new UserFriendlyException("Update Concurrency Happened");
}

В качестве альтернативы можно переопределить SaveChanges и SaveChangesAsync в вашем DbContext, чтобы поймать для всех сущностей:

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        throw new UserFriendlyException("Update Concurrency Happened");
    }
}

public override async Task<int> SaveChangesAsync()
{
    try
    {
        return await base.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        throw new UserFriendlyException("Update Concurrency Happened");
    }
}
0 голосов
/ 27 ноября 2018

Попробуйте отловить как агрегатное исключение ... (Иногда настоящее исключение упаковывается.)

try
{
    // code...
}
catch (Exception ex)
{
    if (ex is AggregateException)
    {
        var exMsg = FlattenAggregate((AggregateException)ex);
        throw new UserFriendlyException(exMsg );
    }

    throw;
}

public static string FlattenAggregate(AggregateException aggregateException)
{
    var sbErr = new StringBuilder();
    var exceptions = aggregateException.Flatten();
    foreach (var exception in exceptions.InnerExceptions)
    {
        sbErr.AppendLine(exception.ToString());
    }

    return sbErr.ToString();
}
...