I'm trying to POST a form to my controller the same way that I used to do with ASP.NET MVC 5 but it's not working.
The controller:
[HttpGet]
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Login([FromBody] Login LoginModel)
{
return View();
}
And HTML
<form asp-action="Login" asp-controller="Home" method="post" class="mt-4">
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label class="text-dark" for="uname">E-mail</label>
<input class="form-control" id="uname" type="text"
placeholder="digite e-mail">
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="text-dark" for="pwd">Senha</label>
<input class="form-control" id="pwd" type="password"
placeholder="digite sua senha">
</div>
</div>
<div class="col-lg-12 text-center">
<button type="submit" class="btn btn-block btn-dark" />
</div>
</div>
</form>
I tried to use the helper:
@using (Html.BeginForm("Login", "Login", FormMethod.Post))
{
}
But the HTML generated doesn't pass the controller path :
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Login}/{id?}");
});
}
It shows action="/"
instead of action="/Home/Login"
on the form since you have set the default route as /Home/Login
:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Login}/{id?}");
});
If you change the default route, it will be displayed correctly.
I have tried your code and the problem is in your model binding.
Firstly, you need to remove [FromBody]
since you are receiving data from a form instead of request body.
Besides, your form does not post data correctly since you do not set the name
attribute or use asp-for
tag helper for your inputs which are used to bind inputs' data to model on action parameters.
Finally, see my complete demo with my assumption Login
model:
public class Login
{
public string uname { get; set; }
public string pwd { get; set; }
}
Login.cshtml( add name
attribute which equal the Login
model's property names):
<form asp-action="Login" asp-controller="Home" method="post" class="mt-4">
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label class="text-dark" for="uname">E-mail</label>
<input class="form-control" name="uname" id="uname" type="text"
placeholder="digite e-mail">
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="text-dark" for="pwd">Senha</label>
<input class="form-control" name="pwd" id="pwd" type="password"
placeholder="digite sua senha">
</div>
</div>
<div class="col-lg-12 text-center">
<button type="submit" class="btn btn-block btn-dark" />
</div>
</div>
</form>
POST action:
[HttpPost]
public async Task<IActionResult> Login(Login LoginModel)