質問

On of the methods I'm having difficulty with is:

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);

I believe there is a bug in the CreateAsync(TUser user, string passwor) method (Microsoft.AspNet.Identity, Microsoft.AspNet.IdentityCore.dll, v2.0.0.0). If I configure the user manager with a password validator and the password doesn't validate, there is no exception (good path) and the IdentityResult looks like

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

However, if pass in an existing user, instead of a nice IdentityResult, the method throws an EntityValidationErrors exception (bad path). I'd like to put the above code back to the original without a try catch and truly rely on the 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);
}

And override the CreateAsync() method:

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;
}

However, I simply don't know how to return a task nor if this is the right direction in terms of fixing the problem.

I suppose I could this the following but using another thread that will just return a value, seems absolutely the wrong route.

result = Task.Factory.StartNew(() =>
{
  return ir;
});
役に立ちましたか?

解決

Simply make your method async, await the task in question, and then just return the alternative value in the catch clause.

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);
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top