Jainendra
Jainendra

Reputation: 25143

Post method not populating values in dictionary

I'm using the following as first line in .cshtml file:

@model Dictionary<string, List<Chapter>>

Get method is working fine. The data in the model I'm displaying in the UI, after post method I'm expecting the dictionary to populate which is not happening. Following is controller post method:

[HttpPost]
public ActionResult Update(Dictionary<string, List<Chapter>> model)

Size of my dictionary is 8, but the result I'm getting has size of two with lists in it null and keys as, "controller" and "action".

How can I fix this?

View:

@model Dictionary<string, List<Chapter>>


    using (Html.BeginForm("Update", "Controller", FormMethod.Post))
    {
    <fieldset>
            <table class="LP3">
            @foreach (string className in Model.Keys)
            {
               @Html.HiddenFor(a => Model[className])
                List<Chapter> cList = Model[className];

                <tr>
                    <th style="width: 50px;">
                    </th>
                    <th style="text-align: left">
                        @className
                    </th>
                    <th style="width: 50px;">
                    </th>
                    <th style="text-align: left">
                    </th>
                    <th style="width: 50px;">
                    </th>
                    <th style="text-align: left">
                    </th>
                </tr>
                for (int i = 0; i < cList.Count / 3; i++)
                {
                <tr>
                    @Html.HiddenFor(a => Model[className][3 * i].id)
                    @Html.HiddenFor(a => Model[className][3 * i].className)

                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][3 * i].included)
                    </td>
                    <td style="text-align: left">
                        @cList[3 * i].name
                        @Html.HiddenFor(a => Model[className][3 * i].name)
                    </td>

                    @Html.HiddenFor(a => Model[className][3 * i + 1].id)
                    @Html.HiddenFor(a => Model[className][3 * i + 1].className)
                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][3 * i + 1].included)
                    </td>
                    <td style="text-align: left">
                        @cList[3 * i + 1].name
                        @Html.HiddenFor(a => Model[className][3 * i + 1].name)
                    </td>

                    @Html.HiddenFor(a => Model[className][3 * i + 2].id)
                    @Html.HiddenFor(a => Model[className][3 * i + 2].className)
                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][3 * i + 2].included)
                    </td>
                    <td style="text-align: left">
                        @Model[className][3 * i + 2].name
                        @Html.HiddenFor(a => Model[className][3 * i + 2].name)
                    </td>
                </tr> 
                }
                if (cList.Count % 3 == 2)
                {
                <tr>
                    @Html.HiddenFor(a => Model[className][cList.Count - 2].id)
                    @Html.HiddenFor(a => Model[className][cList.Count - 2].className)
                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][cList.Count - 2].included)
                    </td>
                    <td style="text-align: left">
                        @cList[cList.Count - 2].name
                        @Html.HiddenFor(a => Model[className][cList.Count - 2].name)
                    </td>
                    @Html.HiddenFor(a => Model[className][cList.Count - 1].id)
                    @Html.HiddenFor(a => Model[className][cList.Count - 1].className)
                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][cList.Count - 1].included)
                    </td>
                    <td style="text-align: left">
                        @Model[className][cList.Count - 1].name
                        @Html.HiddenFor(a => Model[className][cList.Count - 1].name)
                    </td>
                </tr> 
                }
                else if (cList.Count % 3 == 1)
                {
                <tr>
                    @Html.HiddenFor(a => Model[className][cList.Count - 1].id)
                    @Html.HiddenFor(a => Model[className][cList.Count - 1].className)
                    <td style="width: 50px;">
                        @Html.CheckBoxFor(chapterItem => Model[className][cList.Count - 1].included)
                    </td>
                    <td style="text-align: left">
                        @Model[className][cList.Count - 1].name
                        @Html.HiddenFor(a => Model[className][cList.Count - 1].name)
                    </td>
                </tr> 
                }
                <tr style="height: 50px;">
                </tr>
            }
        </table>
    </fieldset>

    }
}

Upvotes: 0

Views: 112

Answers (1)

Dev
Dev

Reputation: 98

You can use a ViewModel to hold the dictionary object. Create a ViewModel like this:

public class YourViewModel
{
      public Dictioanry<string, List<Chapter>> chapters {get; set; }
}

cshtml:

@model ViewModel.YourViewModel
@using ViewModels;

You can set the views like the way you were doing, accessing will be different. Where you were using Model, replace it with Model.chapters and set the model in controller.

also, remove @Html.HiddenFor(a => Model[className]) in cshtml

Upvotes: 1

Related Questions