Reputation: 1759
So I have the following code:
@model Project.Models.ViewModels.SomeViewModel
@using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
{
for(int i = 0; i < Model.SomeCollection.Count(); i++)
{
@Html.HiddenFor(x => Model.SomeCollection.ElementAt(i).Id)
<div class="grid_6">
@Html.TextAreaFor(x => Model.SomeCollection.ElementAt(i).Text, new { @style = "height:150px", @class = "grid_6 input" })
</div>
}
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
On the Controller Side I have the following:
[HttpPost]
public ActionResult SomeAction(int id, SomeViewModel model)
{
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}
My View Model is set up like this:
public class SomeViewModel
{
public SomeViewModel()
{
}
public IEnumerable<ItemViewModel> SomeCollection { get; set; }
}
public class ItemViewModel{
public ItemViewModel(){}
public int Id {get;set;}
public string Text{get;set;}
}
The SomeCollection is always empty when SomeAction if performed. What do I have to do in order to show the updated values by users. Text Property and Id field.
Upvotes: 1
Views: 566
Reputation: 8818
Well, for one thing, why do you have both the model AND id
, a property of model, sent back to the controller? Doesn't that seem a bit redundant? Also, you're using a javascript for
loop in the view. It'd be much easier to just use @foreach
.
Anyway, your problem is that when you tell an action to accept a model, it looks in the post
for values with keys matching the names of each of the properties of the model. So, lets say we have following model:
public class Employee
{
public string Name;
public int ID;
public string Position;
}
and if I'm passing it back like this:
@using(Html.BeginForm("SomeAction", "SomeController"))
{
<input type="text" name = "name" [...] /> //in your case HtmlHelper is doing this for you, but same thing
<input type="number" name = "id" [...] />
<input type="submit" name = "position" [...] />
}
To pass this model back to a controller, I'd have to do this:
//MVC matches attribute names to form values
public ActionResult SomethingPosted(Employee emp)
{
//
}
//MVC matches parameter names to form values
public ActionResult SomethingPosted(string name, int id, string postion)
{
//
}
or this:
//same thing as first one, but without a strongly-typed model
public ActionResult SomethingPosted(FormCollection empValues)
{
//
}
So, here's a better version of your code.
@model Project.Models.ViewModels.SomeViewModel
@{
using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
{
foreach(var item in Model)
{
@Html.HiddenFor(item.Id)
<div class="grid_6">
@Html.TextAreaFor(item.Text, new { @style = "height:150px", @class = "grid_6 input" })
</div>
}
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
}
[HttpPost]
public ActionResult SomeAction(int Id, string Text)
{
//do stuff with id and text
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}
or
[HttpPost]
public ActionResult SomeAction(IEnumerable<ItemViewModel> SomeCollection) //can't use someviewmodel, because it doesn't (directly) *have* members called "Id" and "Text"
{
//do stuff with id and text
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}
Upvotes: 0
Reputation: 218952
Use an EditorTemplate
Create an EditorTemplate folder under your Views/YourcontrollerName and create a view with name ItemViewModel.cshtml
And Have this code in that file
@model Project.Models.ViewModels.ItemViewModel
<p>
@Html.EditorFor(x => x.Text)
@Html.HiddenFor(x=>x.Id)
</p>
Now from your Main view, call it like this
@model Project.Models.ViewModels.SomeViewModel
@using (Html.BeginForm("SomeAction", "Home", new { id = Model.Id}))
{
@Html.EditorFor(s=>s.SomeCollection)
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
Now in your HTTPPOST
method will be filled with values.
I am not sure what you want to do with the values( returning the partial view ?) So not making any comments about that.
Upvotes: 2
Reputation: 2012
I am not sure you have posted all the code.
Your action method does not do anything, since it returns a partial view (for some reason from a post call, not an ajax request) using a new model object.
Your effectively passing a model back to the action and then discarding it, and returning a new model object. This is the reason your collection is always empty, its never set anywhere.
Upvotes: 0