ASP.NET MVC ViewModel inheritance issue

I have the following ViewModels:

public class MyViewModel
{
  public BaseViewModel mySubViewModel;
}

public class ChildViewModel: BaseViewModel
{}

      

Then I create a model MyViewModel that contains a property of type ChildViewModel. In the view it renders just fine.

Then I clicked the save button to submit the changes to my model and I call the following controller:

    [HttpPost]
    public ActionResult Edit(MyViewModel model)
    {
        return null;
    }

      

To my surprise, the mySubViewModel property is now BaseViewModel instead of ChildViewModel! I have no idea what's going on here. What am I doing wrong?

+3


source to share


1 answer


To my surprise, the mySubViewModel property is now BaseViewModel instead of ChildViewModel! I have no idea what will happen here. What am I doing wrong?

You shouldn't be surprised at this. You are not doing anything wrong. This is by design. The binding device sees by default that your controller action takes an argument MyViewModel

and tries to bind the content of the POST request to it. The default binder has absolutely no idea that you could write some derived classes (for example,ChildViewModel

in your case) and what you want those derived classes to be used here. The fact that you passed this specific instance of the viewmodel from your GET action to the view does not affect the POST action. Think of it in terms of HTTP and what the default middleware sees. Consider, for example, that this POST action could be called from a completely different client and not from a form submission. It could be, for example, an iPhone app making an HTTP POST action request. See, now it makes sense. By default, the middleware can only see the POST request payload and the type you specified as the action argument. And what it does => is instantiating these types and binding their properties to the POST payload data.



So there is one possibility to write a custom nexus that will create a specific instance of your ViewModel that you want. I have provided an example of such a custom binder in this post

. In this example, I've included a hidden field inside the form that will contain the specific view model type that we would like to create, and then the custom binding device simply uses that information to create that type at runtime.

+7


source







All Articles