Reputation: 329
Let's say I have a view model like this:
public class MyViewModel
{
//...Other properties and methods...
public MyEntity Entity { get; set;}
}
I use MyViewModel in my view.cshtml
@model MyViewModel
But the POST controller method binds to the MyEntity class, as that's all it needs for the operation.
[HttpPost]
public IActionResult Add(MyEntity entityDetails)
{
if (ModelState.IsValid)
//if valid
return View(new MyViewModel { Entity = entityDetails });
}
The issue is when validating MyEntity, the ModelState contains property names local to that class, whereas the view uses the parent "MyViewModel" class. When I try to retrieve errors for the entity, it can't find any as the ModelState dictionary will contain keys like "Name" and not "Entity.Name".
<form asp-action="Add" method="post">
<input type="text" id="name" name="Name" class="form-control" />
<span asp-validation-for="Entity.Name" class="text-danger"></span>
Is there a way around this? It would be nice if I could specify the "postback" model as well as the "view" model. Or if there was a way to modify the ModelState to prefix the keys with "Entity.". Or to force the asp-validation-for="Name" code to ignore compilation errors (which happens because it can't find the property).
Just to note also, taking MyViewModel in the Add controller action is not ideal. I won't go into the details, but it would make things quite awkward on my view. I could probably do it, but I would like to consider other options.
Upvotes: 0
Views: 814
Reputation: 21546
There are 2 issues in your code that caused the problem.
When you're posting back only partial of the view model, the name of the partial model as the parameter of the controller cannot be arbitrary. It has to match the name you declared inside the view model.
In your case, you called it Entity
in your MyViewModel
, so the parameter of the Add()
method has to be named the same:
[HttpPost]
// public IActionResult Add(MyEntity entityDetails)
public IActionResult Add(MyEntity entity)
{
...
}
I don't get why you used tag helper on the validation but not on the input. The name attribute on the Entity name input should have been name="Entity.Name"
instead of your hard-coded name="Name"
.
And you don't want to hard code it like that. That's what the tag helper is here for.
<form asp-action="Add" method="post">
@*<input type="text" id="name" name="Name" class="form-control" />*@
<input asp-for="Entity.Name" class="form-control" />
<span asp-validation-for="Entity.Name" class="text-danger"></span>
...
If you can fix these two, you should be able to see the key Entity.Name
in the ModelState
:
Upvotes: 1