Search code examples
asp.net-mvccollectionsindexingasp.net-mvc-partialviewasp.net-mvc-viewmodel

MVC handling Collection Item Index in Partial view model


I Have a ViewModel with a collection inside such as:

public class CreateCampaignViewModel : ControlPanelViewModel
{
    [RequiredField]
    public string Name { get; set; }

    public List<AdvertisementViewModel> Advertisements { get; set; }
    ...
}

in the View, if i use it like:

@for (int i = 0; i < Model.Advertisements.Count; i++)
{
  <fieldset style="z-index: 0;">
  <legend>מודעה</legend>
  <table style="width: 100%;">
    <tr>
      <td>
        <label for="@Html.NameFor(m => m.Advertisements[i].Title)">כותרת הפרסומת</label></td>
      <td>@Html.TextBoxFor(m => m.Advertisements[i].Title)</td>
    </tr>
  </table>
  </fieldset>
}

everything is good, and i can see the list when i post the form...

but i want to nest the AdvertisementEditor in a Partial View hence my view becomes:

@for (int i = 0; i < Model.Advertisements.Count; i++)
{
   Html.RenderPartial("AdvertisementEditor", Model.Advertisements[i]);
}

and my Partial:

@model Pushed.Models.AdvertisementViewModel

<fieldset style="z-index: 0;">
    <legend>מודעה</legend>
    <table style="width: 100%;">
        <tr>
            <td>
                <label for="@Html.NameFor(m => m.Title)">כותרת הפרסומת</label></td>
                <td>@Html.TextBoxFor(m => m.Title)</td>
        </tr>
    </table>
</fieldset>

My problem is that Now, when i post the form, i dont get the values in the TextBox for each Advertisement.

This is logical, cause now my <input> tags dont have the 'advertisement[1].Title' name, but only 'Title' which does not exist in my containing model.

how can i create a partial that is reflecting a single collection item with it's indecies so it will repost correctly with the form?


Solution

  • found a solution, Can't believe i didn't find this before!

    there are two ways to tell MVC.NET to prefix input fields:

    1. create EditorTemplate instead of PartialView... and it will work just great.

    2. define TemplateInfo.HtmlFieldPrefix

    calling the Partial View as illustrated:

    @{ 
      Html.RenderPartial("TargetAudienceParameters", Model.TargetAudienceParameter, 
          new ViewDataDictionary {
               TemplateInfo = new TemplateInfo {
                   HtmlFieldPrefix = "Advertisements[4]" // 4 being an example
               } 
          }); 
     }