Passing model IEnumerable property on controller post - ASP MVC

I am working on an asp-MVC application and am facing the following problem: Here is the working code:

<div id="detailsTemplates">
            @for (var i = 0; i < Model.Filter.itemDetails.Count; i++)
            {
                <table>
                    <tr>
                        <td>
                            @Html.TextBoxFor(model => model.Filter.itemDetails[i].iD)
                        </td>

                    </tr>
                </table>
            }

      

Now in the post post in my controller, I have inserted the value correctly.

Now when I change the code to partial view:

<div id="detailsTemplates">
            @for (int i = 0; i < Model.Filter.itemDetails.Count; i++)
            {
                Html.RenderPartial("itemDetailsUserControl", Model.Filter.itemDetails[i]);
            }



        </div>

      

and a partial view looks like this:

<div id="detailsTemplates">
<table>
    <tr>
        <td>
            @Html.TextBoxFor(item => item.iD)
        </td>

    </tr>
</table>
}        

      

Now the value is not passed through the message.

What am I doing wrong?

+3


source to share


1 answer


The context of the model in the view depends on the model passed to it. For example. passing on

Model.Filter.CustomsitemDetails[i]

      

to partial, you changed the root from the Model object to your CustomiseDetails object. (so the input name will be "CustomsItemClassificationID" instead of "Filter.CustomsitemDetails [i] .CustomsItemClassificationID", and therefore there will be no bounce on publish as it no longer matches the property it is bound to.

The correct way to do this is by using the Editor Template . This will keep the original model. To do this, create an EditorTemplates folder under Views> Shared.

Copy the partial into it and rename it to be named after your type. For example, if the Model.Filter.CustomsitemDetails [i] type is customs, then your file in the editor template folder will be named CustomsitemDetails.cshtml.

Now instead of

@Html.RenderPartial("CustomsItemDetailsUserControl", Model.Filter.CustomsitemDetails[i]);

      

Using

@Html.EditorFor(m => m.Filter.CustomitemDetails[i])

      

Also, if you don't want to rename or move the file, you can specify its current location:

@ Html.EditorFor (m => m.Filter.CustomitemDetails [i], "~ / Views / {controller} /CustomsItemDetailsUserControl.cshtml")

UPDATE



So, I learned something new:

If a template whose name matches the templateName parameter is located in the Controller's EditorTemplates folder, that template is used to render the expression. If a template is not found in the Controller's EditorTemplates folder, it looks in the Views \ Shared \ EditorTemplates folder for a template that matches the parameter name templateName. If no template is found, the default template is used. from MSDN .

So, contrary to the second part of my answer, you need to move the partial to

"~/Areas/TaxCalculation/Views/Home/EditorTemplates/CustomsItemDetailsUserControl.cshtml"

      

And use:

@Html.EditorFor(m => m.Filter.CustomitemDetails[i], "CustomsItemDetailsUserControl")

      

UPDATE 2

As per Steven's comment - EditorFor () has an overload that accepts IEnumerable, so you can just use

@Html.EditorFor(m => m.Filter.CustomitemDetails, "CustomsItemDetailsUserControl")

      

Or, if you have an EditorTemplate named CustomitemDetails.cshtml located in the / Views / Shared / EditorTemplates / folder:

@Html.EditorFor(m => m.Filter.CustomitemDetails)

      

+3


source







All Articles