如何将 IEnumerable 从视图发送回控制器
How to send IEnumarable back from View to Controller
我是 MVC 的新手,ASP.Net,我的控制器有 2 个用于 GET 和 POST 的创建方法。通过 Get 方法,我正在生成一个列表并将其发送到视图中。在 View 上,我正在对列表中每个 var 中的特定值进行更改,并尝试将其发送回控制器和 POST 方法。
当到达 Post 方法时,列表的值为空。
我发送的列表是一个产品列表,我正在使用 ViewModel 创建一个 class 具有要传递给视图的公共值。
要传递由我尝试使用 BeginCollectionForm 的视图编辑的 IEnumarable 集合,通过 ViewBag 设置项目,
更改模型 (@model IEnumerable)
但每次按下“结帐”按钮时,Post 方法中的列表仍然为 NULL。
经过多次尝试和修改,目前我的代码如下所示:
OrderController.cs(相关部分)
public class OrderController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Create()
{
var meals = (from m in db.meals
select new ItemVM
{
Id = m.Id,
Name = m.Name,
Price = m.Price,
ItemType = "Meal",
ImageURL = m.ImageUrl,
Quantity = 0
}).ToList();
var drinks = (from d in db.drinks
select new ItemVM
{
Id = d.Id,
Name = d.Name,
Price = d.Price,
ItemType = "Drink",
Quantity = 0
}).ToList();
//More Like That....
List<ItemVM> items = new List<ItemVM>();
items.AddRange(meals);
items.AddRange(drinks);//More Like...
return View(items.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(IEnumerable<ItemVM> items = null)
{
//Here items equals to null.
if (ModelState.IsValid)
{
//.....
}
return View();
}
Views/Order/Create.cshtml:
@model IEnumerable<***.ViewModel.ItemVM>
@{
ViewBag.Title = "Create";
var lst = Model.ToList();
ViewBag.List = Model.ToList();
}
<style>
tr td {
vertical-align: middle;
}
</style>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h3> Order:</h3>
<table class="table table-condensed table-hover">
<tr calss="table-header">
<th>
@Html.DisplayName("Preview")
</th>
<th>
@Html.DisplayNameFor(m => m.Name)
</th>
<th>
@Html.DisplayNameFor(m => m.Price)
</th>
<th>
@Html.DisplayName("Quantity")
</th>
<th></th>
<th></th>
</tr>
@for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
@if (Model.ElementAt(i).ImageURL != null)
{
<img src="@Url.Content(Model.ElementAt(i).ImageURL)" alt="IMAGES" height="100" width="100" />
}
</td>
<td>
@Html.DisplayFor(m => Model.ElementAt(i).Name)
</td>
<td>
@Html.DisplayFor(m => Model.ElementAt(i).Price)
</td>
<td>
<a type="button" class="btn btn-danger btn-xs" href="#">
<span class="glyphicon glyphicon-minus"></span>
</a>
@Html.EditorFor(l => lst[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => lst[i].Quantity, "", new { @class = "text-danger" })
<a type="button" class="btn btn-success btn-xs" id="plus" href="#">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Checkout" class="btn btn-primary"/>
</div>
</div>
}
ViewModel/ItemVM.cs:
namespace ***.ViewModel
{
public class ItemVM
{
[Required]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
[Required]
public string ItemType { get; set; }
public string ImageURL { get; set; }
[Required]
public int Quantity { get; set; }
}
}
最后我想用"Create"(HttpPost方法)
根据从视图接收到的列表中的值创建新订单。
这样做并将 IEnumarable 接收到 POST 方法中的正确方法是什么?
好的,我终于能够让它工作了。
我已将 @model
更改为列表类型,
将 (actionName, Controller, FormMethod)
添加到 HTML 助手 Html.BeginForm
,
在循环内使用 Model[i]
来访问变量和
标记所有未更改的变量
@Html.HiddenFor.
Create.cshtml:
@model List<MarsBurgerV1.ViewModel.ItemVM>
@{
ViewBag.Title = "Create";
}
@using (Html.BeginForm("Create","Order", FormMethod.Post))
{
@Html.AntiForgeryToken()
<h3> Order:</h3>
<table class="table table-condensed table-hover">
<tr calss="table-header">
<th>
@Html.DisplayName("Preview")
</th>
<th>
@Html.DisplayName("Name")
</th>
<th>
@Html.DisplayName("Price")
</th>
<th>
@Html.DisplayName("Quantity")
</th>
<th></th>
<th></th>
</tr>
@for (var i = 0; i < Model.Count(); i++)
{
<tr>
@Html.HiddenFor(m => Model[i].Id)
@Html.HiddenFor(m => Model[i].Type)
<td>
@Html.HiddenFor(m => Model[i].ImageURL)
@if (Model[i].ImageURL != null)
{
<img src="@Url.Content(Model[i].ImageURL)" alt="IMAGES" height="100" width="100" />
}
@Html.ValidationMessageFor(model => Model[i].ImageURL, "", new { @class = "label-control" })
</td>
<td>
@Html.HiddenFor(m => Model[i].Name)
@Html.DisplayFor(m => Model[i].Name)
@Html.ValidationMessageFor(model => Model[i].Name, "", new { @class = "label-control" })
</td>
<td>
@Html.HiddenFor(m => Model[i].Price)
@Html.DisplayFor(m => Model[i].Price, new { @class = "form-control" })
@Html.ValidationMessageFor(model => Model[i].Price, "", new { @class = "label-control" })
</td>
<td>
<a type="button" class="btn btn-danger btn-xs" href="#">
<span class="glyphicon glyphicon-minus"></span>
</a>
@Html.EditorFor(model => Model[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => Model[i].Quantity, "", new { @class = "text-danger" })
<a type="button" class="btn btn-success btn-xs" id="plus" href="#">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" value="Checkout" class="btn btn-primary"/>
</div>
</div>
}
感谢大家的帮助。
我是 MVC 的新手,ASP.Net,我的控制器有 2 个用于 GET 和 POST 的创建方法。通过 Get 方法,我正在生成一个列表并将其发送到视图中。在 View 上,我正在对列表中每个 var 中的特定值进行更改,并尝试将其发送回控制器和 POST 方法。 当到达 Post 方法时,列表的值为空。 我发送的列表是一个产品列表,我正在使用 ViewModel 创建一个 class 具有要传递给视图的公共值。
要传递由我尝试使用 BeginCollectionForm 的视图编辑的 IEnumarable 集合,通过 ViewBag 设置项目, 更改模型 (@model IEnumerable) 但每次按下“结帐”按钮时,Post 方法中的列表仍然为 NULL。
经过多次尝试和修改,目前我的代码如下所示: OrderController.cs(相关部分)
public class OrderController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Create()
{
var meals = (from m in db.meals
select new ItemVM
{
Id = m.Id,
Name = m.Name,
Price = m.Price,
ItemType = "Meal",
ImageURL = m.ImageUrl,
Quantity = 0
}).ToList();
var drinks = (from d in db.drinks
select new ItemVM
{
Id = d.Id,
Name = d.Name,
Price = d.Price,
ItemType = "Drink",
Quantity = 0
}).ToList();
//More Like That....
List<ItemVM> items = new List<ItemVM>();
items.AddRange(meals);
items.AddRange(drinks);//More Like...
return View(items.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(IEnumerable<ItemVM> items = null)
{
//Here items equals to null.
if (ModelState.IsValid)
{
//.....
}
return View();
}
Views/Order/Create.cshtml:
@model IEnumerable<***.ViewModel.ItemVM>
@{
ViewBag.Title = "Create";
var lst = Model.ToList();
ViewBag.List = Model.ToList();
}
<style>
tr td {
vertical-align: middle;
}
</style>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h3> Order:</h3>
<table class="table table-condensed table-hover">
<tr calss="table-header">
<th>
@Html.DisplayName("Preview")
</th>
<th>
@Html.DisplayNameFor(m => m.Name)
</th>
<th>
@Html.DisplayNameFor(m => m.Price)
</th>
<th>
@Html.DisplayName("Quantity")
</th>
<th></th>
<th></th>
</tr>
@for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
@if (Model.ElementAt(i).ImageURL != null)
{
<img src="@Url.Content(Model.ElementAt(i).ImageURL)" alt="IMAGES" height="100" width="100" />
}
</td>
<td>
@Html.DisplayFor(m => Model.ElementAt(i).Name)
</td>
<td>
@Html.DisplayFor(m => Model.ElementAt(i).Price)
</td>
<td>
<a type="button" class="btn btn-danger btn-xs" href="#">
<span class="glyphicon glyphicon-minus"></span>
</a>
@Html.EditorFor(l => lst[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => lst[i].Quantity, "", new { @class = "text-danger" })
<a type="button" class="btn btn-success btn-xs" id="plus" href="#">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Checkout" class="btn btn-primary"/>
</div>
</div>
}
ViewModel/ItemVM.cs:
namespace ***.ViewModel
{
public class ItemVM
{
[Required]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
[Required]
public string ItemType { get; set; }
public string ImageURL { get; set; }
[Required]
public int Quantity { get; set; }
}
}
最后我想用"Create"(HttpPost方法) 根据从视图接收到的列表中的值创建新订单。 这样做并将 IEnumarable 接收到 POST 方法中的正确方法是什么?
好的,我终于能够让它工作了。
我已将 @model
更改为列表类型,
将 (actionName, Controller, FormMethod)
添加到 HTML 助手 Html.BeginForm
,
在循环内使用 Model[i]
来访问变量和
标记所有未更改的变量
@Html.HiddenFor.
Create.cshtml:
@model List<MarsBurgerV1.ViewModel.ItemVM>
@{
ViewBag.Title = "Create";
}
@using (Html.BeginForm("Create","Order", FormMethod.Post))
{
@Html.AntiForgeryToken()
<h3> Order:</h3>
<table class="table table-condensed table-hover">
<tr calss="table-header">
<th>
@Html.DisplayName("Preview")
</th>
<th>
@Html.DisplayName("Name")
</th>
<th>
@Html.DisplayName("Price")
</th>
<th>
@Html.DisplayName("Quantity")
</th>
<th></th>
<th></th>
</tr>
@for (var i = 0; i < Model.Count(); i++)
{
<tr>
@Html.HiddenFor(m => Model[i].Id)
@Html.HiddenFor(m => Model[i].Type)
<td>
@Html.HiddenFor(m => Model[i].ImageURL)
@if (Model[i].ImageURL != null)
{
<img src="@Url.Content(Model[i].ImageURL)" alt="IMAGES" height="100" width="100" />
}
@Html.ValidationMessageFor(model => Model[i].ImageURL, "", new { @class = "label-control" })
</td>
<td>
@Html.HiddenFor(m => Model[i].Name)
@Html.DisplayFor(m => Model[i].Name)
@Html.ValidationMessageFor(model => Model[i].Name, "", new { @class = "label-control" })
</td>
<td>
@Html.HiddenFor(m => Model[i].Price)
@Html.DisplayFor(m => Model[i].Price, new { @class = "form-control" })
@Html.ValidationMessageFor(model => Model[i].Price, "", new { @class = "label-control" })
</td>
<td>
<a type="button" class="btn btn-danger btn-xs" href="#">
<span class="glyphicon glyphicon-minus"></span>
</a>
@Html.EditorFor(model => Model[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => Model[i].Quantity, "", new { @class = "text-danger" })
<a type="button" class="btn btn-success btn-xs" id="plus" href="#">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" value="Checkout" class="btn btn-primary"/>
</div>
</div>
}
感谢大家的帮助。