Get list data on view in controller

2019-04-21 17:24发布

问题:

I have a view in which I have rendered partial view in a loop. There is a list and partial view have is binded with each item in a list. I am not getting the value of the list on controller after value is entered.

Here is my view:

<table id="resourceRequirement" class="table" width="100%" border="0">
    <thead>
        <tr style="background-color:#dfdfdf;">
            <td><div align="center">PRIORITY</div></td>
            <td><div align="center">SYSTEM RESOURCE / COMPONENT</div></td>
            <td><div align="center">RECOVERY TIME OBJECTIVE</div></td>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.ResourceRequirement)
        {
            @Html.Partial("~/Views/Shared/_ResourceRequirement.cshtml", item)
        }
    </tbody>
</table>

Here is my partial view:

@model DisasterManagementSystem.Models.BusinessImpactAnalysis.ResourceRequirement
<tr>
    <td>
        @Html.TextBoxFor(m => m.priority)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.priority)
        </div>
    </td>
    <td>
        @Html.TextBoxFor(m => m.systemresource)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.systemresource)
        </div>
    </td>
    <td>
        @Html.TextBoxFor(m => m.receveryTime)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.receveryTime)
        </div>
    </td>
</tr>

Here is my list:

public List<ResourceRequirement> ResourceRequirement { get; set; }

And the class is here:

public class ResourceRequirement
{
    [Required(ErrorMessage = "*")]
    public string priority { get; set; }

    [Required(ErrorMessage = "*")]
    public string systemresource { get; set; }

    [Required(ErrorMessage = "*")]
    public string receveryTime { get; set; }
}

Please advise when i am trying to get the list from model on post I am getting the list as null.

回答1:

You use of a foreach loop and a partial is generating duplicate name attributes without indexers (so cannot bind to a collection) and duplicate id attributes (invalid html).

Instead of a partial view, use an EditorTemplate. Rename your current partial view to ResourceRequirement.cshtml (i.e. to match the name of the class) and place it in the /Views/Shared/EditorTemplates folder (or in the /Views/yourController/EditorTemplates folder)

Then in the main view, remove the foreach loop and replace it with

<tbody>
    @Html.EditorFor(m => m.ResourceRequirement)
</tbody>

The EditorFor() method accepts IEnumerable<T> and generates the correct html for each item in your collection. If you inspect the html you will now see the correct name attributes in your form controls

<input type="text" name="ResourceRequirement[0].priority" .... />
<input type="text" name="ResourceRequirement[1].priority" .... />
<input type="text" name="ResourceRequirement[2].priority" .... />

etc. which will bind to your model when you submit the form (compare this with what your currently generating)



回答2:

As You want List to be passed in the View just in Controller pass the List through a method like

public Actionresult List()
{
  var search = from m in db.resourcerequirement select m;
  return PartialView("_List",search.tolist());
}

After that in Partial View _List

@model DisasterManagementSystem.Models.BusinessImpactAnalysis.ResourceRequirement
<tr>
    <td>
        @Html.TextBoxFor(m => m.priority)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.priority)
        </div>
    </td>
    <td>
        @Html.TextBoxFor(m => m.systemresource)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.systemresource)
        </div>
    </td>
    <td>
        @Html.TextBoxFor(m => m.receveryTime)<br />
        <div style="color:red;">
            @Html.ValidationMessageFor(model => model.receveryTime)
        </div>
    </td>
</tr>

To show Partial View

@{Html.RenderAction("List", "ControllerName");}