0

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.

1 Answer 1

1

There are 2 issues in your code that caused the problem.

1. The name of model posted back to the controller

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)
{
    ...
}

2. The name of the Entity name input

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:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

that's great, thanks. That helped me fix my problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.