我是ASP.NET MVC 5(VS2013)的新手,并尝试构建一个可以添加和删除项目的简单购物篮。
我遇到的问题是,当我单击ADD按钮时,添加的行不会像我预期的那样递增ID。它始终返回0(在呈现给浏览器的HTML中),因此单击时删除按钮会删除所有条目(所有ID都匹配)。
我试图在没有AJAX和TempData / Session / ViewBag / ViewData的情况下这样做,以便我可以更好地学习"自动模型绑定"(其中发布的值绑定到属性)。
控制器\ ShoppingBasketController.cs
public class ShoppingBasketController : Controller
{
public ActionResult Index()
{
ShoppingBasketViewModel vm = new ShoppingBasketViewModel();
return View(vm);
}
[HttpPost]
public ActionResult Index(ShoppingBasketViewModel vm, string ButtonClicked)
{
if (ButtonClicked.ToLower() == "add")
{
return AddShoppingBasketItem(vm);
}
else if (ButtonClicked.ToLower().Contains("remove_"))
{
return RemoveShoppingBasketItem(vm, ButtonClicked);
}
else
{
return View(vm);
}
}
private ActionResult AddShoppingBasketItem(ShoppingBasketViewModel vm)
{
vm.Items.Add(new ShoppingBasketItemViewModel() { Id = vm.NextId, Name = String.Format("Name {0}", vm.NextId) });
vm.NextId++;
return View(vm);
}
private ActionResult RemoveShoppingBasketItem(ShoppingBasketViewModel vm, string WhichRemoveButtonClicked)
{
int idToDelete = 0;
bool success = int.TryParse(WhichRemoveButtonClicked.Split('_').LastOrDefault(), out idToDelete);
if (!success)
{
throw new ArgumentException("WhichRemoveButtonClicked", String.Format("Could not get Id to delete from the button clicked. '{0}", WhichRemoveButtonClicked));
}
vm.Items.RemoveAll(item => item.Id == idToDelete);
return View(vm);
}
}
模型\ ShoppingBasketViewModel.cs
public class ShoppingBasketViewModel
{
public int NextId { get; set; }
public List<ShoppingBasketItemViewModel> Items { get; set; }
public ShoppingBasketViewModel()
{
this.Items = new List<ShoppingBasketItemViewModel>();
}
}
模型\ ShoppingBasketItemViewModel.cs
public class ShoppingBasketItemViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
〜/查看/共享/ DisplayTemplates / ShoppingBasketViewModel.cshtml
@model ShoppingBasketKyle.Models.ShoppingBasketViewModel
@* Format the rendered HTML to have line breaks *@
@Environment.NewLine
<table border="1">
<tr>
<td>ID</td>
<td>Name</td>
<td>Remove</td>
</tr>
@for (int count = 0; count < Model.Items.Count; count++)
{
<tr>
<td>@Html.DisplayFor(x => x.Items[count].Id)</td>
<td>@Html.DisplayFor(x => x.Items[count].Name)</td>
<td><input type="submit" name="ButtonClicked" value="Remove_@Html.DisplayFor(x => x.Items[count].Id)"/></td>
</tr>
}
</table>
@* Persist ShoppingBasketItems (Collection) property by posting them back *@
@for (int count = 0; count < Model.Items.Count; count++)
{
@Environment.NewLine
@Html.HiddenFor(x => x.Items[count].Id)
@Environment.NewLine
@Html.HiddenFor(x => x.Items[count].Name)
}
@* Persist the NextId property by posting it back *@
@Environment.NewLine
@Html.HiddenFor(x => x.NextId)
〜/ ShoppingBasket / Index.cshtml
@model ShoppingBasketKyle.Models.ShoppingBasketViewModel
@Html.ValidationSummary(true)
@using (Html.BeginForm())
{
@Html.DisplayForModel()
<input type="submit" name="ButtonClicked" value="Add" class="btn btn-primary btn--small" />
}
任何问题随时可以提出
TIA
凯尔
答案 0 :(得分:0)
我设法对此进行排序,但不明白为什么。该问题似乎是由.HiddenFor()MVC帮助器方法引起的。在搜索到SO之后,它似乎有一个错误或设计做了你想要的事情。因此,我更新以下内容:
〜/查看/共享/ DisplayTemplates / ShoppingBasketViewModel.cshtml
@model ShoppingBasketKyle.Models.ShoppingBasketViewModel
@* Format the rendered HTML to have line breaks *@
@Environment.NewLine
<table border="1">
<tr>
<td>ID</td>
<td>Name</td>
<td>Remove</td>
</tr>
@for (int count = 0; count < Model.Items.Count; count++)
{
<tr>
<td>@Html.DisplayFor(x => x.Items[count].Id)</td>
<td>@Html.DisplayFor(x => x.Items[count].Name)</td>
<td><input type="submit" name="ButtonClicked" value="Remove_@Html.DisplayFor(x => x.Items[count].Id)" /></td>
</tr>
}
@* Persist ShoppingBasketItems (Collection) property by posting them back *@
@for (int count = 0; count < Model.Items.Count; count++)
{
@Environment.NewLine
<input type="hidden" id="Items[@count.ToString()].Id" name="Items[@count.ToString()].Id" value="@Model.Items[count].Id" />
@Environment.NewLine
<input type="hidden" id="Items[@count.ToString()].Name" name="Items[@count.ToString()].Name" value="@Model.Items[count].Name" />
}
@* Persist the NextId property by posting it back *@
@Environment.NewLine
<input type="hidden" id="NextId" name="NextId" value="@Model.NextId" />
@Environment.NewLine
我将编写一个扩展方法来动态获取viewmodel属性名称,因此如果重命名,我将不必在视图中手动维护html
欢呼声