I am new to MVC. i have problem to pass data from view to controller.
This application is for ordering Shirts. I have different types like T-shirts, Casual shirts and Formal Shirts. In a single order, I would like to place order for 2 T-shirts, 3 Casual shirts and 5 Formal Shirts. I am able to edit single value, i.e. either of them, in one order. The problem I am facing is with ordering multiple types of shirts in one order.
public class Shirt
{
//[Key]
public int ShirtId{ get; set; }
public string ShirtName{ get; set; } // This is an read-only field
}
public class Order
{
public int ShirtId { get; set; }
public virtual Shirt Shirt { get; set; } // a reference to Shirt
public int Quantity { get; set; }
public int OrderId { get; set; }
}
I have a view that is strongly typed with my viewmodel “Order”. Initially I passed data from my Controller to View using
[HttpGet]
public ActionResult Index()
{
OrdersList();
return View(db.Order.ToList());
}
Here OrdersList is a function that interacts with database and gets a list of Orders
void OrdersList()
{
ViewBag.OrdersLsit= from f in db.Shirt
orderby f.ShirtName
select f;
}
I am getting data back to Controller using,
[HttpPost]
public ActionResult Index(List<Order> order)
{
Order newOrder = new Order();
for (int i = 0; i < order.Count; i++)
{
newOrder.Quantity = order.ElementAt(i).Quantity;
if (ModelState.IsValid)
{
db.Entry(newOrder).State = EntityState.Modified;
db.SaveChanges();
}
}
}
My problem is List order is passed as Null. If I do
public ActionResult Index(Order order) in HttpPost, I am getting only the first item(in this case a T shirt is getting updated in database).
In Index.cshtml, I am doing something like this
<legend>Order Shirts</legend>
<table>
<tr>
@{List<Order> orderList = new List<Order>(); }
@foreach (Order ord in ViewBag.OrderList)
{
<td>
@Html.DisplayFor(model => ord.Shirt.Shirtname)
</td>
orderList.Add(ord);
}
</tr>
<tr>
@for (int i = 0; i < orderList.Count; i++)
{
<td class = "editorClass">
@Html.HiddenFor(model => orderList.ElementAt(i).Shirt.ShirtId)
@Html.HiddenFor(model => orderList.ElementAt(i).OrderId)
@Html.ValidationSummary(true)
@Html.HiddenFor(model => orderList.ElementAt(i).ShirtId)
@Html.EditorFor(model => orderList.ElementAt(i).Quantity)
@Html.ValidationMessageFor(model => orderList.ElementAt(i).Quantity)
</td>
}
</tr>
</table>
</fieldset>
<p>
<input id = "btnSubmit" type="submit" value="Save Order" />
</p>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
I am new to MVC and this is my first application. Any constructive comments and suggestions are appreciated.
Thanks
I don’t understand why you are creating
orderListinstead the view, actually you have to pass that from the controller and strongly type the view toList<Order>.Instead of using this,
You could try (if you strongly type the view to
List<Order>),If the view is not strongly typed to
List<Order>you could try this,But in this case you have to change the action as below,
The reason is I’m not sure whether the
ElementAt(i)generate the names properly for fields, so try index approach!