I'm not able to get ReturnUrl
to work on HttpPost
using ASP.NET Core 6 MVC.
When adding a breakpoint to the POST
method, returnurl
is always null. But with .NET 5, it works with the same code setup except that with .NET 6, I need to make the returnurl
parameter nullable so that I won't get an error "returnurl field is required".
This is the code I'm using - any help would be much appreciated.
Thanks.
Model:
namespace IdentityManagerDotNet6.Models
{
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; } = string.Empty;
[Required]
[DataType(DataType.Password)]
public string Password { get; set; } = string.Empty;
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
}
Controller
[HttpGet]
public IActionResult Login(string? returnurl)
{
ViewData["ReturnUrl"] = returnurl;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel loginViewModel, string? returnurl)
{
ViewData["ReturnUrl"] = returnurl;
returnurl = returnurl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(loginViewModel.Email, loginViewModel.Password, loginViewModel.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
return LocalRedirect(returnurl);
}
if (result.IsLockedOut)
{
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(loginViewModel);
}
}
return View(loginViewModel);
}
View:
@model LoginViewModel
<h1 >Log in</h1>
<div >
<div >
<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" role="form">
<h4>Use a local account to log in</h4>
<hr />
<div asp-validation-summary="All" ></div>
<div >
<label asp-for="Email" ></label>
<div >
<input asp-for="Email" />
<span asp-validation-for="Email" ></span>
</div>
</div>
<div >
<label asp-for="Password" ></label>
<div >
<input asp-for="Password" />
<span asp-validation-for="Password" ></span>
</div>
</div>
<div >
<input asp-for="RememberMe" type="checkbox" value="" id="flexCheckChecked">
<label asp-for="RememberMe" for="flexCheckChecked">
Remember me?
</label>
</div>
<div >
<div >
<button type="submit" asp-controller="Account" asp-action="Login" >Login</button>
</div>
</div>
<p>
<a asp-action="Register">Register as a new user?</a>
</p>
<p>
<a asp-action="ForgotPassword">Forgot your passord?</a>
</p>
</form>
</div>
</div>
CodePudding user response:
"I'm not able to get ReturnUrl to work on HttpPost using ASP.NET Core 6 MVC.":
I have checked your code between the line. It doesn't has anything wrong with
[FromQuery]
So you don't need to do anything on[FromQuery]
as other answer I've seen, may be deleted now.
Issue Replication:
I have reproduced your issue successfully as you can see below:
What Causing the Issue:
If you investigate your code again you would noticed that you are using
asp-controller="Login" asp-action="Login"
twice on yourLogin.cshtml
at the begining of theform
and at the point ofsubmit button
this causing the data loss while you are submitting the form.
At the starting on form:
<form asp-controller="Login" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" role="form">
At your button submit::
<button type="submit" asp-controller="Login" asp-action="Login" >Login</button>
Solution:
The easiest solution is just modify your submit button code
like below which will resolve your issue:
<div >
<div >
<button type="submit" >Login</button>
</div>
</div>
Output:
Hope it will resolve your returnurl
null issue completely.