I have a login page, in the page model there is a property called LoginDTO (custom class of mine). Within this are only two strings - username and password.
On the login page I have a login form with two fields, you can probably guess what they are. The code is here:
<div class="form-group">
<input class="form-control" type="email" name="email" placeholder="Email" asp-for="LoginDTO.Username">
</div>
<div class="form-group">
<input class="form-control" type="password" name="password" placeholder="Password" asp-for="LoginDTO.Password">
</div>
I fill out the input fields and hit submit (form method set as POST
, I have an OnPost
method in the page model to handle it), for some reason LoginDTO.Username
is null however LoginDTO.Password
is populated?? Therefore, of course, the ModelState is invalid and there is no Username
string to use.
How can this be? I've tried renaming the variable and setting it as value="@Model.LoginDTO.Username"
instead of using asp-for
, neither made any difference.
Can anyone help?
UPDATE: I changed the Username
property to Email
and it's now started working?! Why do the name of these properties affect if they can be assigned values?!?!
I changed the Username property to Email and it's now started working?! Why do the name of these properties affect if they can be assigned values?!?!
Firsly,you need know that for each property of the complex type, model binding looks through the sources for the name pattern prefix.property_name
. If nothing is found, it looks for just property_name
without the prefix.
Reference:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#complex-types
Then you need know that asp-for
tag helper would generate the html like below by default:
<input id="LoginDTO_Username" name="LoginDTO.Username">
But you add the name
property to the input element,so it would override the name
property,it would render the html like below:
<input id="LoginDTO_Username" name="email">
So the model binding system could not find the username
source.That is why it could work after you change the Username
property to Email
.
For your scenario,if you do not want to change the model property name,you could change like below:
<input class="form-control" type="email" name="username" placeholder="Email" asp-for="LoginDTO.Username">
Or just using the asp-for
tag helper:
<div class="form-group">
<input class="form-control" type="email" placeholder="Email" asp-for="LoginDTO.Username">
</div>
<div class="form-group">
<input class="form-control" type="password" placeholder="Password" asp-for="LoginDTO.Password">
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With