Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return List or Collection to Controller from View in MVC 3?

Someone please help me return this list properly from my view. I don't see why I'm returning null for my fieldModelList I try to pass to the controller...

Here is my view:

@model List<Regions.SOA.UI.CopyBookSchemaCreator.Models.FieldModel>

<script type="text/javascript" src="~/Scripts/jquery-ui-1.8.11.min.js"></script>

@using (Html.BeginForm("GetResponse", "TestMethods", FormMethod.Post))
{

<table id="tblMethods">
    <tr>
        <th>
            Property Name
        </th>
        <th>
            Request
        </th>
    </tr>

    @foreach (FieldModel fieldModel in Model) 
    {
        <tr>
            <td>
                @Html.DisplayFor(m => fieldModel.PropertyName)
            </td>
            <td>
                @Html.TextBoxFor(m => fieldModel.PropertyValue)
            </td>
        </tr>
    }

</table>

<div>
    <input type="submit"/>       
</div>

and here is my controller:

    [HttpPost]
    public ActionResult GetResponse(List<FieldModel> fieldModelList)
    {
        return GetResponse(fieldModelList);   
    }

I am hitting the HttpPost method but if I place a breakpoint just inside it, I am returning null for the fieldModelList right off the bat, which I was hoping would be a list of the values I entered into the texboxes on the view that is of model FieldModel...

I think something is wrong with my logic versus my syntax, or as maybe as well as my syntax, but basically what I want to do is return back a list of type FieldModel with each corresponding PropertyName and PropertyValue to the controller. I noticed I am not passing any kind of id parameter in my BeginForm statement in the view. Do I need one here?

Just in case, here is my model class for FieldModel:

namespace Regions.SOA.UI.CopyBookSchemaCreator.Models
{
    public class FieldModel
    {
        [Display(Name = "Property")]
        public string PropertyName { get; set; }

    [Display(Name = "Value")]
        public string PropertyValue { get; set; }
    }
}
like image 706
ob1Jakobi Avatar asked Feb 09 '12 20:02

ob1Jakobi


1 Answers

Phil Haack wrote an article some time ago explaining how to bind collections (ICollection) to view models. It goes into additional detail about creating an editor template, which you could certainly do as well.

Basically, you need to prefix the HTML elements' name attributes with an index.

<input type="text" name="[0].PropertyName" value="Curious George" />
<input type="text" name="[0].PropertyValue" value="H.A. Rey" />

<input type="text" name="[1].PropertyName" value="Ender's Game" />
<input type="text" name="[1].PropertyValue" value="Orson Scott Card" />

Then, your controller could bind the collection of FieldModel

[HttpPost]
public ActionResult GetResponse(List<FieldModel> fieldModelList)
{
    return GetResponse(fieldModelList);   
}

I'm not 100% sure the following would name the attributes correctly (I'd recommend using the editor template) but you could easily use the htmlAttributes argument and give it a name using the index.

@for(int i = 0;i < Model.Count;i++) 
{
    <tr>
        <td>
            @Html.DisplayFor(m => m[i].PropertyName)
        </td>
        <td>
            @Html.TextBoxFor(m => m[i].PropertyValue)
        </td>
    </tr>
}

Editor Template

If you wanted to go as far as adding an editor template, add a partial view named FieldModel.ascx to /Views/Shared that is strongly typed to a FieldModel

@model Regions.SOA.UI.CopyBookSchemaCreator.Models.FieldModel

@Html.TextBoxFor(m => m.PropertyName) @* This might be a label? *@
@Html.TextBoxFor(m => m.PropertyValue)

And, then the part of your view responsible for rendering the collection would look like:

@for (int i = 0; i < Model.Count; i++) { 
    @Html.EditorFor(m => m[i]);
}
like image 173
David Fox Avatar answered Oct 20 '22 02:10

David Fox