Sachin Kainth
Sachin Kainth

Reputation: 46750

Model not populated on Post

I have this in a partial view

@using (Html.BeginForm(MVC.Inventory.ActionNames.AddVehicles, MVC.Inventory.Name, new { model = Model.Items }))
{
   <div><button>@AuctionControllerResource.AddToBiddingProcess</button></div>
}

The post method is this

[HttpPost]
        public virtual ActionResult AddVehicles(List<VehicleViewModel> model)
        {
            return null;
        }

When I put a breakpoint in the view I can see that Model.Items has 1 item in it as it should. However, when I hit the Post action method on button click, there are no items in the model.

I have added this in the form

@Html.HiddenFor(m => m.Items)

but it doesn't help.

What am I doing wrong?

thanks,

Sachin

EDIT

Additional code

 public class ListViewModel<T> : IQuery
        where T : class
    {

        public List<T> Items { get; set; }
     ...
}

Upvotes: 0

Views: 1493

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038990

The following doesn't do what you think it does:

new { model = Model.Items }

You cannot pass complex objects like that. You will have to generate hidden fields in the form if you want this to work.

I have added this in the form

@Html.HiddenFor(m => m.Items)

No, it's normal that it doesn't help. The hidden field works only with simple types. You wil have to loop through the items in the collection and generate corresponding fields for each property of each element:

@using (Html.BeginForm(MVC.Inventory.ActionNames.AddVehicles, MVC.Inventory.Name))
{
    for (var i = 0; i < Model.Items.Count; i++)
    {
        @Html.HiddenFor(x => x.Items[i].Prop1)
        @Html.HiddenFor(x => x.Items[i].Prop2)
        @Html.HiddenFor(x => x.Items[i].ComplexProp3.Prop1)
        @Html.HiddenFor(x => x.Items[i].ComplexProp3.Prop2)
        ...
    }
    <div>
       <button>@AuctionControllerResource.AddToBiddingProcess</button>
    </div>
}

But this seems quite a waste. Since the user cannot modify those values anyway in the form, I would recommend you simply passing an id which will allow you to retrieve the corresponding items from your data store in the POST action:

@using (Html.BeginForm(MVC.Inventory.ActionNames.AddVehicles, MVC.Inventory.Name, new { id = Model.ItemsId }))
{
    <div>
       <button>@AuctionControllerResource.AddToBiddingProcess</button>
    </div>
}

and then:

[HttpPost]
public virtual ActionResult AddVehicles(int id)
{
    List<VehicleViewModel> model = GetItemsFromDataStore(id);
    ...
}

Upvotes: 2

Related Questions