0

I have a collection of entities, called Accounts. A single user will have multiple Accounts and can set percentages for each Account.

The UI will list all the Accounts, the editable field for each Account is the Percentage property. This will be represented by a textbox.

Once the user makes any adjustments, they will post the form back for processing.

I have used MVC in a few other projects and I understand model binding, but I am not sure how to proceed when dealing with a collection of models.

I am not looking for code or for someone to write out the complete answer for me (although, honestly I wouldn't complain....). I am looking for guidance in the direction to take.

Thanks in advance.

Shai Cohen
  • 6,074
  • 4
  • 31
  • 54

2 Answers2

1

Two things:

1) You'll want to use a List/Collection of Account or List/Collection of AccountViewModel in your overarching page view model

So, you would have

public class MyPageViewModel
{
    public Collection<Account> AccountList; 
    //AccountViewModel is what I'd use but for simplicity
    //Other properties for view model
}

You now have a view model that contains a list of accounts.

2)

In your view you have two options.

a) Just create a for loop to spit out the HTML you want for each account (not especially pretty)

b) Create an editor template so you don't have to do anything special Your page would then have this.

@Html.EditorFor(model => model.AccountList)

Here's how editor templates are set up.

enter image description here

This is from a project I'm working on right now. The take away here should be that you add an "EditorTemplates" folder under the view folder that matches what you're working on. By convention, MVC will look in this folder for a template when you use EditorFor. Now you just insert whatever HTML you want in that strongly typed template (which would take an Account or AccountViewModel object) and you'd be done. No need for a for loop in your view to spit out HTML for each account.

Really, that would be it at that point. Your post action would model bind to a type of MyPageViewModel which would have the updated data you wanted

Hope that gets you pointed in the right direction.

Khepri
  • 9,547
  • 5
  • 45
  • 61
  • Thanks for the detailed answer. +1. I do have a question though, you said "Your post action would model bind to a type of MyPageViewModel". Does this apply to a collection as well? – Shai Cohen May 16 '12 at 18:37
  • Yes it does. Based on my image above we have some really complex view models that contain multiple collection view models, sometimes a few levels deep and they all bind up nice and neatly. EDIT: Unless you're asking can you model bind to a List directly. See this link for info on that: http://stackoverflow.com/questions/653514/asp-net-mvc-model-binding-an-ilist-parameter and also http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx – Khepri May 16 '12 at 18:56
  • Yes I was asking about binding to an IList directly. I also came across the haacked article. That solved the problem for me. Thanks again. – Shai Cohen May 16 '12 at 19:09
1

Here is an example of how to solve your task

First lets define a model:

public class Account
{
    public int Id { get; set; }
    public string Number { get; set; }
    public decimal Percentage { get; set; }
}

public class UserEditModel
{
    public ICollection<Account> Accounts { get; set; }
}

UserEditModel is a view model. It contains property Accounts declared as collection of Account.

I'll describe a table in a view to show accounts and edit their percentages:

<form action="Url.Action("Save")" method="POST">
<table>
  <thead>
    <tr>
       <td>Number</td>
       <td>Percentage</td>
    </tr>
  </thead>
  <tbody>
    @for (var i = 0; i < Model.Accounts.Count(); i ++)
    {
      <tr>
         <td>
            @Html.HiddenFor(m => m.Accounts[i].Id)
            @Html.HiddenFor(m => m.Accounts[i].Number)
            @Model.Accounts[i].Number
         </td>
         <td>
            @Html.TextBoxFor(m => m.Accounts[i].Id)
         </td>
      </tr>
    }
  </tbody>
</table>
</form>

After submitting the form in Accounts property of the view model we'll have changed by user values of percentages.

Alex
  • 361
  • 4
  • 5