如何捕获违反数据库约束并抛出 UserFriendlyException?
How to catch DB constraint violation and throw UserFriendlyException?
我有一个 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
行似乎是hidden/ignored.
我该怎么做才能解决这个问题?
谢谢。
您在使用 ASP.NET Core 吗?
因为在 ABP 文档中:(https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions)
本文档适用于 ASP.NET MVC 和 Web API。如果您对 ASP.NET 核心感兴趣,请参阅 ASP.NET 核心文档。
我必须使用 TempData 和 ViewBag 以模式向用户显示错误...
I tried catching it in an override of the Create()
method but it does not get catched.
您需要致电_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 中覆盖 SaveChanges
和 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.SaveChanges();
}
catch (DbUpdateException ex)
{
throw new UserFriendlyException("A message for the user");
}
}
我有一个 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
行似乎是hidden/ignored.
我该怎么做才能解决这个问题?
谢谢。
您在使用 ASP.NET Core 吗?
因为在 ABP 文档中:(https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions) 本文档适用于 ASP.NET MVC 和 Web API。如果您对 ASP.NET 核心感兴趣,请参阅 ASP.NET 核心文档。
我必须使用 TempData 和 ViewBag 以模式向用户显示错误...
I tried catching it in an override of the
Create()
method but it does not get catched.
您需要致电_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 中覆盖 SaveChanges
和 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.SaveChanges();
}
catch (DbUpdateException ex)
{
throw new UserFriendlyException("A message for the user");
}
}