Gideon
Gideon

Reputation: 113

ASP.NET MVC: Binding dynamically rendered partial views as nested properties of the view model

I have the following view models:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public BankAccount BankAccount { get; set; }
    public PayPalAccount PayPalAccount { get; set; }
}

public class BankAccount
{
    public string BankName { get; set; }
    public string AccountNumber { get; set; }
}

public class PayPalAccount
{
    public string PayPalEmail { get; set; }
}

In my single view I have a form that binds the Person model and also has a DropDownList that let's the user choose an account type.

Once the user makes his choice, I load dynamically using jQuery ajax one of the partial views that represent either the BankAccount or the PayPalAccount and I add it to the page.

After the user clicks submit, I call this action:

public ActionResult Save(Person person)
{ 
    // Here I expect that either person.BankAccount or person.PayPalAccount 
    // will contain the user input, and the other will be null
}

How do I make the partial view properties bind to the nested property in my Person view model?

Upvotes: 0

Views: 1709

Answers (1)

JotaBe
JotaBe

Reputation: 39014

Your form fields must be prefixed (with BankAccount. or PayPalAccount.) so that they can be automatically bound.

When you return your partial view from Ajax, withthe current model you're using, their names don't have a prefix.

The easier way to prefix them is using exactly the same View Model class: Person for both partial views. If you do that, in the Razor you'll have to write

@Html.EditorFor(m => m.BankAccount.BankName)

The generated input field will have the required prefix BankAccount., i.e. it will look like this: <input ... name='BankAccount.BankName' ... />

You could also create a view model like this for your partial:

public class BakAccountModel
{
   // make sure the property name is the same as in the Person view model
   public BankAccount { get; set; } 
}

An finally, you can try a solution like this: ASP.NET MVC partial views: input name prefixes

I can't assure the last solution will work fine: for example it could break the ModelState. And is harder to implemente and "less standard".

Upvotes: 2

Related Questions