【问题标题】:Override async method with exception handling on result使用结果异常处理覆盖异步方法
【发布时间】:2014-05-14 19:51:57
【问题描述】:

我遇到困难的方法是:

if (ModelState.IsValid)
{
    var user = new User { UserName = model.Email, Email = model.Email };
    IdentityResult result = null;
    try
    {
        result = await this._userManager.CreateAsync(user, model.Password).Result;
    }
    catch (Exception ex)
    {
    }

    if (result != null && result.Succeeded)
    {
      // not important code
    }
    AddErrors(result);
}

// If we got this far, something failed, redisplay form
return View(model);

我认为CreateAsync(TUser user, string passwor) 方法(Microsoft.AspNet.Identity、Microsoft.AspNet.IdentityCore.dll、v2.0.0.0)中存在错误。如果我使用密码验证器配置用户管理器并且密码未验证,则没有异常(良好路径)并且IdentityResult 看起来像

Errors      {string[1]}
- string[]  {string[1]}
-- [0]      "Passwords must have at least...."

但是,如果传入现有用户,而不是好的 IdentityResult,则该方法会引发 EntityValidationErrors 异常(错误路径)。我想把上面的代码放回原来的没有try catch,真正依赖IdentityResult

if (ModelState.IsValid)
{
    var user = new User { UserName = model.Email, Email = model.Email };

    var result = this._userManager.CreateAsync(user, model.Password);

    if (result.Succeeded)
    {
      // not important code
    }
    AddErrors(result);
}

并覆盖CreateAsync() 方法:

public override Task<IdentityResult> CreateAsync(User user, string password)
{
    Task<IdentityResult> result = null;
    try
    {
        var ir = base.CreateAsync(user, password);

        return ??;
    }
    catch (DbEntityValidationException ex)
    {
        var errors = ex.EntityValidationErrors
            .Where(e => e.IsValid)
            .SelectMany(e => e.ValidationErrors)
            .Select(e => e.ErrorMessage)
            .ToArray();
        var ir = new IdentityResult(errors);

        return ??;
    }

    return result;
}

但是,我根本不知道如何返回任务,也不知道这是否是解决问题的正确方向。

我想我可以这样做,但使用另一个只会返回一个值的线程,似乎绝对是错误的路线。

result = Task.Factory.StartNew(() =>
{
  return ir;
});

【问题讨论】:

    标签: c# asynchronous asp.net-identity-2


    【解决方案1】:

    只需将您的方法asyncawait 设置为有问题的任务,然后在catch 子句中返回替代值。

    public override async Task<IdentityResult> CreateAsync(User user, string password)
    {
        try
        {
            return await base.CreateAsync(user, password);
        }
        catch (DbEntityValidationException ex)
        {
            var errors = ex.EntityValidationErrors
                .Where(e => e.IsValid)
                .SelectMany(e => e.ValidationErrors)
                .Select(e => e.ErrorMessage)
                .ToArray();
            return new IdentityResult(errors);
        }
    }
    

    【讨论】:

    • 我不能return base.CreateAysnc(),因为它不会抛出异常,直到.Result 属性被访问,它在这个try/catch 之外。
    • @ErikPhilips 对,在这种情况下,只需创建方法async,生活就会变得轻松。
    • 我不知道我可以在override 上添加async
    • @ErikPhilips async 对方法的公共 API 没有影响。尽管在方法的签名中,从技术上讲,任何调用该方法的人都不需要知道或关心它是否是async。显然,他们需要知道它是否在更一般的意义上是异步的,但是可以使用或不使用 async 来使方法异步。 (此外,async 方法实际上可以是同步的,如果它什么都不等待。)
    猜你喜欢
    • 2018-11-06
    • 2019-03-19
    • 2018-09-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2023-03-27
    • 2011-09-11
    • 2019-08-29
    相关资源
    最近更新 更多