我目前感到困惑的是为什么我的方法没有运行。我在它上面放了一个断点,因为我怀疑某些地方有些失败。
以下是我的解释:
我刚刚开始使用新的ASP.NET MVC 2应用程序。我将我的Home / Index页面连接到一个新的强类型视图,我创建了一个名为Categories / List的视图。 Everything显示正常 - 从我的实体数据模型中检索并放置在页面上的类别。我删除了使用视图自动创建的“详细信息”链接。
之后,我向类别/删除添加了强类型删除视图。在我的CategoriesController中,我有以下代码(哪个有效)
<%: Html.ActionLink("Delete", "DeleteCategory", new { id=item.CategoryID })%>
为:
/// <summary>
/// Get rid of a Category
/// </summary>
/// <returns>Redirect to ~/Categories/Delete</returns>
public ActionResult DeleteCategory(int id)
{
ViewData.Model = (from c in DataContext.Categories where c.CategoryID == id select c).FirstOrDefault();
return View("Delete");
}
我的删除视图如下所示:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<PracticeApp.Models.Category>" %>
删除
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Fields</legend>
<div class="display-label">CategoryID</div>
<div class="display-field"><%: Model.CategoryID %></div>
<div class="display-label">Category1</div>
<div class="display-field"><%: Model.Category1 %></div>
</fieldset>
<% using (Html.BeginForm()) { %>
<p>
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "List") %>
</p>
<% } %>
确定。这对MVC专家来说似乎都很熟悉。记住,我刚开始使用MVC并且我对Linq Either没有非常好的知识,所以我期待从我的下面的代码中发现一些火焰(甚至没有运行 - 问题的目的 - 我不知道为什么它不运行!)
它在我的categoriesController
中 [HttpPost]
public ActionResult Delete(Models.Category category)
{
foreach (Models.Category c in DataContext.Categories)
{
if (c.CategoryID == category.CategoryID)
{
DataContext.Categories.DeleteObject(c);
}
}
DataContext.SaveChanges();
return RedirectToAction("List", "List", "Categories");
}
为什么我的代码拒绝运行的任何想法?我突破了第一个支架。断点永远不会到达。
答案 0 :(得分:1)
问题是,您没有在确认页面上发布表单中的任何内容。因此,MVC无法绑定到类别模型。
要获取要删除的项目的ID,请使用与普通视图相同的方法:
[HttpPost]
public ActionResult Delete(int id)
{
//delete item
}
执行此操作时,您可能会收到错误,因为有两种方法具有相同的重载。在那里,我通常会创建一个额外的参数,并为其提供一个值以及发布的表单,如下所示:
[HttpPost]
public ActionResult Delete(int id, bool confirm)
{
foreach (Models.Category c in DataContext.Categories)
{
if (c.CategoryID == category.CategoryID)
{
DataContext.Categories.DeleteObject(c);
}
}
DataContext.SaveChanges();
return RedirectToAction("List", "List", "Categories");
}
您的表单将如下所示:
<% using (Html.BeginForm()) { %>
<p>
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "List") %>
</p>
<input type="hidden" name="confirm" value="true" />
<% } %>
有一件事总能帮助我,提醒自己MVC页面(就像任何网页一样)都是无状态的。因此,您当前的请求对您之前的请求一无所知。您在此过程中需要的任何数据,您必须自己完成。因此,如果要绑定类别,则必须提供表单中类别的数据。因为您在页面上显示了模型,所以并不意味着您的下一个请求仍然可以使用此数据。
答案 1 :(得分:1)
问题是您的GET操作(DeleteCategory
)与您的POST操作(Delete
)不同。
因此,您需要指定要调用的操作:
<% using (Html.BeginForm("Delete", "Categories")) { %>
或者如果您不想这样做,您应该将您的GET方法重命名为与POST方法相同:
// Access this action with /Categories/Delete
public ActionResult Delete(int id)
{
var model = DataContext.Categories.FirstOrDefault(x => x.CategoryID == id);
return View(model);
}
[HttpPost]
public ActionResult Delete(Category category)
{
...
}
既然你的GET和POST动作都以相同的方式命名,你可以使用不带参数的BeginForm
助手,因为这些动作之间的区别将基于用于调用它们的HTTP动词:
<% using (Html.BeginForm()) { %>
作为表单内的旁注,您没有任何输入字段。所以不要期望从你的POST动作所期望的这个类别中得到任何东西。您可能至少需要包含一个隐藏字段,其中包含您愿意删除的类别的ID。
答案 2 :(得分:0)
我以为我会发布完成的结果。 Pbirkoff通过Hidden Field帮助了很多,我完全忘记了它甚至存在,Darin帮我研究了我的问题。
[HttpPost]
public ActionResult Delete(int CategoryID,FormCollection FC)
{
DC.Categories.DeleteObject((from c in DC.Categories where c.CategoryID == CategoryID select c).FirstOrDefault());
DC.SaveChanges();
return RedirectToAction("list", "categories");
}
这是一个从零开始的娱乐项目。 DC是我的实体数据模型(缩短了DataContext,但这只是一个练习应用程序)。
我将此添加到我的删除视图中。
“%&gt;删除
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Fields</legend>
<div class="display-label">CategoryID</div>
<div class="display-field"><%: Model.CategoryID %></div>
<div class="display-label">Category1</div>
<div class="display-field"><%: Model.Category1 %></div>
</fieldset>
<% using (Html.BeginForm()) { %>
<p>
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "List") %>
</p>
**<input type="hidden" name="CategoryID" value = "<%: Model.CategoryID %>" />**
<% } %>
(隐藏字段。请注意**不在实际代码中。它指出我添加的内容)