(已解决)如何强制捕获异常? (或检索异常变量)

(SOLVED) How do I force the catch exception? (or retrieve exception variable)

如何强制我的 else 语句转到 catch 异常?我得到了这个代码:

try
{
    user.UserName = editedUser.Username;
    user.Email = editedUser.Email;
    user.RowVersion = editedUser.RowVersion;

    var result = await userManager.UpdateAsync(user);

    if (result.Succeeded)
    {
        return RedirectToAction("ListOfUsers");
    }
    else
    {
        Somehow go to Catch(DbUpdateConcurrencyException ex) // <---------- How?
    }
}
catch (DbUpdateConcurrencyException ex)
{
    var exceptionEntry = ex.Entries.Single();
    var clientValues = (ApplicationUser)exceptionEntry.Entity;
    var databaseEntry = exceptionEntry.GetDatabaseValues();

    if (databaseEntry == null)
    {
        ModelState.AddModelError(string.Empty, $"User{editedUser.ID} was deleted before you applied the changes.");
    }
    else
    {
        var databaseValues = (ApplicationUser)databaseEntry.ToObject();

        if (databaseValues.UserName != clientValues.UserName)
        {
            ModelState.AddModelError("Username", $"Current username in Database: {databaseValues.UserName}");
        }
        if (databaseValues.Email != clientValues.Email)
        {
            ModelState.AddModelError("Email", $"Current email in Database: {databaseValues.Email}");
        }

        ModelState.AddModelError(string.Empty, "The user you were trying to edit was modified by someone else. Editing operation was canceled and the current values ​​in the database are now shown below. If you still want to edit this user, click Save again, otherwise click Undo");

        user.RowVersion = databaseValues.RowVersion;
        ModelState.Remove("RowVersion");
    }
}

我需要使用 DbUpdateConcurrencyException ex 变量来获取我的数据库条目值。

如果可以在 else 语句中获取这些数据库条目值,我该怎么做?

编辑 - 解决方案: 我发现我们应该避免这种情况并处理代码中的错误,而不是使用 Try/catch,即 if-else。在 else 语句中,我找到了 Identity 使用的异常,并进行了处理。并获取数据库值,我使用了:

var dbUser = await userManager.Users.AsNoTracking().SingleOrDefaultAsync(x => x.Id == user.Id);

通过这样做,我可以比较 'dbUser' 和 'user' 的属性。

我明白你在追求什么,但是方法完全错误。

DbUpdateConcurrencyException 是 EF Core 特定的异常,而身份是抽象框架,因此设计的这个异常永远不会流动,因此永远不会命中 catch

根据设计,错误通过 IdentityResult.Errors 提供,并发问题默认提供 IdenitityError.Code 等于“ConcurrencyFailure”,可以在 EF Core store implementation 中看到:

try
{
   await SaveChanges(cancellationToken);
}
catch (DbUpdateConcurrencyException)
{
   return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}

所以你需要重构代码。删除整个 catch 块,并在 else 子句中检查并发错误,如果是,则使用 UserManager.FindByIdAsync 获取当前(数据库)数据并执行您的逻辑。

像这样:

else
{
    var concurrencyError = result.Errors.FirstOrDefault(error =>
        error.Code == nameof(IdentityErrorDescriber.ConcurrencyFailure));
    if (concurrencyError != null)
    {
        var dbUser = await userManager.FindByIdAsync(user.Id);
        // Check for null(deleted) or modified properties here
    }
}