抛出异常回滚并同时重定向到另一个动作

Throw exception to rollback and redirect to another action at the same time

我正试图在发生异常时将一个操作重定向到另一个操作。另外,我想回滚 所有的变化同时发生。回滚数据是通过抛出异常来完成的,但是当我们抛出异常时,重定向不起作用。 (我使用了一个在抛出异常时自动处理回滚的框架(ABP),所以我的代码中没有 "BeginTransaction" 和 "Commit" 等。)

当代码运行时,它只是回滚对数据的更改并显示异常而不是重定向。

[HttpPost]
public async Task<ActionResult> action1()
{
    var exception=false;

    try
    {
        await method1();

        return RedirectToAction("Success", "Result");
    }
    catch (Exception e)
    {
        exception = true;
        return RedirectToAction("ShowError", "Result");
    }
    finally
    {
        if (exception == true)
            throw new Exception("1000"); 
    }
}

public async Task<ActionResult> method1()
{
    // Some changes on database
}

In addition I want to rollback all changes at same time. Rollbacking data needs throw exception and when we throw an exception, redirect not working.

你不能有方法return结果抛出异常;非此即彼。

您可以做的是抛出异常 - 这会导致回滚 - 然后在您的操作方法中捕获它并 return 结果:

[HttpPost]
public async Task<ActionResult> action1()
{
  try
  {
    await method1();
    return RedirectToAction("Success", "Result");
  }
  catch (Exception e)
  {
    return RedirectToAction("ShowError", "Result");
  }
}

ABP 的 Conventional Unit of Work 范围围绕您的控制器操作 action1

您应该需要一个在您的 try 块范围内的新工作单元:

[HttpPost]
public async Task<ActionResult> action1()
{
    try
    {
        using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
        {
            await method1();
            uow.Complete();
        }

        return RedirectToAction("Success", "Result");
    }
    catch (Exception e)
    {
        return RedirectToAction("ShowError", "Result");
    }
}

或者,您可以制作 method1 virtual 并用 UnitOfWork 属性标记它:

[HttpPost]
public async Task<ActionResult> action1()
{
    try
    {
        await method1();

        return RedirectToAction("Success", "Result");
    }
    catch (Exception e)
    {
        return RedirectToAction("ShowError", "Result");
    }
}

[UnitOfWork(TransactionScopeOption.RequiresNew)]
public virtual async Task<ActionResult> method1()
{
    // Some changes on database
}

参考:How to return -1 in catch block (aspnetboilerplate/aspnetboilerplate#2732)