I catch post request from 3rd-side static page (generated by Adobe Muse) and handle it with MVC action.
I had the same problem and I want to share what happened in my case and how I got the solution. Perhaps, someone may find it useful to know.
My context was ASP.NET Core 3.1 Razor pages. I had a handler as
public async Task<JsonResult> OnPostLogin([FromForm] LoginInput loginData)
{
}
and also I had a property in my ViewModel as
public LoginInput LoginInput { get; set; }
And in my Razor page, I have used the form like this:
<form asp-page-handler="Login" method="post">
<input asp-for="LoginData.UserNameOrEmail">
.....
So, notice that, in my form, I used the property LoginInput.UserNameOrEmail, but in my handler's parameter, I used the parameter name loginData. How will the ASP.NET Core know that, this LoginInput.UserNameOrEmail is actually loginData.UserNameOrEmail. It can't, right? Therefore, it did not bind my form data.
Then, when I renamed my ViewModel property "LoginInput" to the same name as the handler parameter, like this:
public LoginInput LoginData { get; set; }
The ASP.NET Core then found that the form data was matching the parameter name and then it started to bind properly. My problem was solved.
I ran into this today, and though in hindsight it seems obvious, just thought I'd add that you need to make sure your access modifiers for the Properties on the model you're binding are correct. I had public MyProperty { get; internal set; }
on some and they would not bind. Removed internal
and they worked just fine.
I'm having the same problem this docs helps me to understand Model Binding https://docs.asp.net/en/latest/mvc/models/model-binding.html
I solved my problem by making sure that the property name is exact match in form field name and I also add [FromForm] attribute to specify exactly the binding source.
Be careful not to give an action parameter a name that is the same as a model property or the binder will attempt to bind to the parameter and fail.
public async Task<IActionResult> Index( EmailModel email ){ ... }
public class EmailModel{ public string Email { get; set; } }
Change the actions parameter 'email' to a different name and it will bind as expected.
public async Task<IActionResult> Index( EmailModel uniqueName ){ ... }