2
votes

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?!?!

1

1 Answers

1
votes

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://docs.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>