确认身份中的电子邮件时AmbiguousActionException

时间:2018-10-26 09:34:51

标签: c# asp.net-core asp.net-core-2.0

我正在使用Web服务来管理用户注册。

我不明白,因为获得了这个:

  

AmbiguousActionException:多个动作匹配。以下动作与路线数据匹配,并且满足所有约束条件:

     

Test.Api.Controllers.AccountsController.ConfirmEmail(Test.Api)   Test.Api.Controllers.AccountsController.ResetPassword(Test.Api)

这是我的代码

[HttpPost]
[AllowAnonymous]
[Route("register")]
public async Task<IActionResult> Register([FromBody]RegistrationViewModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var userIdentity = _mapper.Map<AppUser>(model);
    var result = await _userManager.CreateAsync(userIdentity, model.Password);

    if (!result.Succeeded) return new BadRequestObjectResult(Errors.AddErrorsToModelState(result, ModelState));

    var token = await _userManager.GenerateEmailConfirmationTokenAsync(userIdentity);
    var callbackUrl = Url.EmailConfirmationLink(userIdentity.Id, token, Request.Scheme);
    await _emailSender.SendEmailAsync(model.Email, "Confirm ",     $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>");

    await _appDbContext.Customers.AddAsync(new Customer { IdentityId = userIdentity.Id, Location = model.Location });
    await _appDbContext.SaveChangesAsync();

    return new OkObjectResult("Account created");
}

我为该代码的callbackUrl做了一个助手:

public static string EmailConfirmationLink(this IUrlHelper urlHelper, string userId, string token, string scheme)
{
    return urlHelper.Action(
        action: nameof(AccountsController.ConfirmEmail),
        controller: "Accounts",
        values: new { userId, token },
        protocol: scheme);
}

public async Task<IActionResult> ConfirmEmail(string userId, string token)
{
    if (userId == null || token == null)
    {
        return new BadRequestResult();
    }

    var user = await _userManager.FindByIdAsync(userId);
    if (user == null)
    {
        throw new ApplicationException($"Unable to load user with ID '{userId}'.");
    }
    var result = await _userManager.ConfirmEmailAsync(user, token);
    if (!result.Succeeded)
    {
        return new BadRequestResult();
    }
    await _emailSender.SendEmailAsync(user.Email, "Account confermato","Il tuo account è stato confermato");
    return new OkObjectResult("Account confirmed");
}

public IActionResult ResetPassword(string code = null)
{
    if (code == null)
    {
        throw new ApplicationException("A code must be supplied for password reset.");
    }
    var model = new ResetPasswordViewModel { Code = code };
    return View(model);
}

这两种方法(ConfirmEmail(字符串userId,字符串令牌)和ResetPassword(字符串代码= null))如何可能造成歧义?这两个角色是不同的

1 个答案:

答案 0 :(得分:1)

您在关于问题的评论中指出AccountsController具有以下属性:

[Route("api/[controller]")]

这意味着您的ConfirmEmailResetPassword动作正在使用相同的路径,在这种情况下,其简称为api/Accounts。在浏览器中加载此路由后,这两个操作都是处理请求的候选方法,因此您会收到问题中所述的错误。

为了解决此问题,有几种选择:

  1. [Route("ConfirmEmail")]添加到ConfirmEmail并将[Route("ResetPassword")]添加到ResetPassword(类似于您对Register操作所做的操作)。
  2. [Route("[action]")]ConfirmEmail中都添加ResetPassword,其中[action]是动作名称的占位符。
  3. 从您的[Route("register")]操作中删除Register,并将控制器的属性更新为[Route("api/[controller]/[action]")]。您还需要从其他任何操作中删除[Route(...)]。请注意,仅当您的所有操作均根据api/[controller]/[action]模式进行路由时,这种方法才可行。