我正在使用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))如何可能造成歧义?这两个角色是不同的
答案 0 :(得分:1)
您在关于问题的评论中指出AccountsController
具有以下属性:
[Route("api/[controller]")]
这意味着您的ConfirmEmail
和ResetPassword
动作正在使用相同的路径,在这种情况下,其简称为api/Accounts
。在浏览器中加载此路由后,这两个操作都是处理请求的候选方法,因此您会收到问题中所述的错误。
为了解决此问题,有几种选择:
[Route("ConfirmEmail")]
添加到ConfirmEmail
并将[Route("ResetPassword")]
添加到ResetPassword
(类似于您对Register
操作所做的操作)。[Route("[action]")]
和ConfirmEmail
中都添加ResetPassword
,其中[action]
是动作名称的占位符。[Route("register")]
操作中删除Register
,并将控制器的属性更新为[Route("api/[controller]/[action]")]
。您还需要从其他任何操作中删除[Route(...)]
。请注意,仅当您的所有操作均根据api/[controller]/[action]
模式进行路由时,这种方法才可行。