2

I'm trying to pass the values of checkboxs from view to controller. here are my code

In model:

public partial class ORDER_HEADER_INFO
{
   //many other fields 
    public bool checkExport { get; set; }
}

In Controller:

 [HttpPost]
 public void ExportCSV(List<Models.ORDER_HEADER_INFO> model) {
        foreach (Models.ORDER_HEADER_INFO item in model) {
              if (item.checkExport) {
                 //Do somethings
              }
         }

In View:

@model IEnumerable<TIS.Models.ORDER_HEADER_INFO>
@using (Html.BeginForm("ExportCSV", "MKP_004", FormMethod.Post)){
  <input type="submit" value="ExportCSV" />
  @foreach (var item in Model)
    {DateTime deadline = new DateTime(2015, 04, 12);
        var className = (item.PRODUCT_START_DATE >= deadline) ? "selected" : null;
        <tr class="@className">
            <td>
                @Html.ActionLink(item.ORDER_NO, "MKP_003", "MKP_003", new { id = item.ORDER_NO }, new { })
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.MODEL)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PJNO)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.DELIVERY_DESTINATION)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PRODUCT_START_DATE)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FINISH_FLAG)
            </td>
            <td>
               @Html.CheckBoxFor(modelItem => item.checkExport)
            </td>
        </tr>        
    }
</table>
}

My expected outcome is i can get the list of selected items then do some work with them. In parameter of the method. I had tried:

List<Models.ORDER_HEADER_INFO> model

and

IEnumerable<TIS.Models.ORDER_HEADER_INFO> model

but when i debug the model is still null.

Many thanks!

Tran Duy Linh
  • 221
  • 1
  • 9
  • 1
    Your `foreach` loop is generating duplicate `id` attributes (invalid html) and `name` attributes (which can't be bound to a collection) for the checkboxes. Use a `for` loop of a custom `EditorTemplate` for typeof `ORDER_HEADER_INFO` - `for(int i = 0; i < Model.Count; i++) { @Html.CheckBoxFor(m => m[0].checkExport) }` Inspect the html before and after to see the difference –  Apr 23 '15 at 04:46
  • When i use for(int i = 0; i < Model.Count; i++) there is a notice that Operator "<" can not be applied to operands of type "int" and "method group" – Tran Duy Linh Apr 23 '15 at 04:59
  • Make the model `@model IList` (or `List<...>`) –  Apr 23 '15 at 05:02
  • How can i replace this "item.PRODUCT_START_DATE". Sorry, I'm totally new with MVC 4 – Tran Duy Linh Apr 23 '15 at 05:08
  • 1
    Exactly the same way - inside the `for` loop - `@Html.DisplayFor(m => m[0].PRODUCT_START_DATE)` (dreadful naming BTW - follow convention and use ProductStartDate). But you have other problems as well. Your model has a property named `MODEL` and you have also named the parameter in your method `model` so binding will fail (you need to change one or the other) –  Apr 23 '15 at 05:15
  • I try to change code to be List and IList, now It passed all the model from view to controller. Can you tell me the difference between List, IList and IEnumberable – Tran Duy Linh Apr 23 '15 at 05:21
  • Suggest you research that yourself [IList vs IEnumerable](https://www.google.com.au/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=ilist%20vs%20ienumerable) –  Apr 23 '15 at 05:27
  • @TranDuyLinh, like Stephen Muecke suggestion use for loop instead of foreach. I think this link will help you http://stackoverflow.com/a/22497568/2501044 – Golda Apr 23 '15 at 05:47
  • See this SO Question http://stackoverflow.com/questions/17037858/how-to-pass-ienumerable-list-to-controller-in-mvc-including-checkbox-state – 111 Apr 23 '15 at 05:52

1 Answers1

0

As others have mentioned, you simply need to rewrite your foreach to be a for loop so that it applies indexing to the name attributes of the HTML fields, in order for the model binder to do it's work. Change your foreach to be:

@for (int i = 0; i < Model.Count(); i++)
{DateTime deadline = new DateTime(2015, 04, 12);
    var className = (Model[i].PRODUCT_START_DATE >= deadline) ? "selected" : null;
    <tr class="@className">
        <td>
            @Html.ActionLink(Model[i].ORDER_NO, "MKP_003", "MKP_003", new { id = Model[i].ORDER_NO }, new { })
        </td>
        <td>
            @Html.DisplayFor(m => m[i].Model)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].PJNO)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].DELIVERY_DESTINATION)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].PRODUCT_START_DATE)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].FINISH_FLAG)
        </td>
        <td>
           @Html.CheckBoxFor(m => m[i].checkExport)
        </td>
    </tr>        
}
Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148