我正在将ASP.NET Boilerplate与代码优先实体框架和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");
}
}
}
答案 0 :(得分:1)
尝试捕获作为总体异常... (有时,真正的异常正在被包装。)
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();
}
答案 1 :(得分:1)
UpdateAsync(branch)
仅将branch
添加到上下文中。
注入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");
}
}