For some reason, when I use a child property as an asp-for
value, the HTTP Post
model property shows that they were not modified and my ModelState
validation does not trigger.
Here is the example - view
@model ViewModel
<form asp-action="Login" asp-controller="App" method="POST">
<input asp-for="subClass1.user.email_addr" type="text" class="form-control" autocomplete="on" />
<input asp-for="test" type="text" class="form-control" autocomplete="on" />
</form>
Model
public class ViewModel
{
public string test { get; set; } = "test value";
public User subClass1 = new User();
}
public class User
{
public UserL user { get; set; } = new UserL();
}
public class UserL
{
[CustomEAttribute]
public string? email_addr { get; set; }
}
HTTP POST
method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(ViewModel model, Microsoft.AspNetCore.Http.IFormCollection collection)
{
// I've also found ModelState is not triggered on subClass1
// properties... only the 'test' property triggered.
if (!ModelState.IsValid)
{
}
}
From what I can tell in my controller, the property ViewModel model
has not changed (ie not returning my view input value) for email_addr
.
I've tried using @Html.TextBoxFor
instead of plain html input and I still have no luck.
So many examples online say you should be able to do my example above without issues so not sure what is wrong with my code.
I do know the Microsoft.AspNetCore.Http.IFormCollection
collection property does show subClass1.user.email_addr
being set. So why does accessing that same value in "model" not work?
When defining a data model in the ASP.NET MVC it's necessary to use properties not fields. If fields are used the MVC engine will not able to make data binding correctly. Change the view model declaration to:
public class ViewModel
{
public string test { get; set; } = "test value";
public User subClass1 { get; set; } = new User();
}