【问题标题】:Delete Action fails in MVCMVC 中的删除操作失败
【发布时间】:2015-04-07 10:27:01
【问题描述】:

我正在尝试像这样从索引视图页面中删除一个实体

@using (Html.BeginForm())
{
     @Html.AntiForgeryToken()
     <button type="submit" value="delete" formaction="/Issue/Delete">Delete</button>
}

在此按钮上单击我希望我的 DeleteConfirmed Action 在控制器内发生(而不是转到另一个删除页面)。

内部控制器

  [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        Issue issue = _db.Issues.Find(id);
        _db.Issues.Remove(issue);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }

现在它会抛出一个错误

参数字典包含参数“id”的空条目 方法的不可空类型“System.Int32” 'System.Web.Mvc.ActionResult DeleteConfirmed(Int32)' 在 'DiagnosisApp.Controllers.IssueController'。可选参数必须 是引用类型、可为空的类型或被声明为可选项 参数。

参数名称:参数

谁能指出实现这一目标的正确方法是什么?

【问题讨论】:

  • 也发布您的删除操作代码。
  • 与问题无关,但最好不要使用硬编码的网址,而是使用 @Url 助手。
  • 您需要将 Id 传递给您的操作方法。
  • @JenishRabadiya 怎么样?可以添加代码示例吗?
  • id从哪里来?网格?用户输入?视图模型?请显示一些代码。

标签: c# asp.net-mvc


【解决方案1】:

您没有在 POST 或 URL 中提供 ID。

POST 到包含 ID 的 URL:

@using (Html.BeginForm("Delete", "Controller", new { id = Model.ID }, FormMethod.Post))
{
    // ...
}

或将 ID 发布为隐藏的表单值:

@using (Html.BeginForm("Delete", "Controller", FormMethod.Post))
{
    @Html.HiddenFor(m => m.ID)
    // ...
}

【讨论】:

  • 你假设 id 在模型中......我们都知道这个假设是所有 f*ckups 的母亲。
  • @Paul 当然,但是 OP “试图从索引视图页面中删除一个实体”,因此在打印此表单时,他处于某种循环中。然后 OP 可以用currentModel.ID 替换Model.ID 或用m =&gt; m.AllModels[i].ID 替换m =&gt; m.ID(或者通过使用DisplayTemplates,省略循环的需要)。是的,这假设在一个实体中存在一个 ID,其余代码都指向该实体(DeleteConfirmed(int id)、_db.Issues.Find(id))。
【解决方案2】:

从错误中

参数字典包含参数“id”的空条目

告诉我们你实际上并没有向你的控制器传递任何东西。因此,要将 id 值“传递”给您的控制器,您可以使用类似于以下内容的ActionLink:

@Html.ActionLink("Delete", "Delete", new { id=item.PrimaryKeyValue })

在视图中使用模型的数据。


此“ActionLink”将链接到您的控制器中的 CRUD 脚手架(我相信您已经在其中使用);

类似这样的:

 // GET: message/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            message message = db.messages.Find(id);
            if (message == null)
            {
                return HttpNotFound();
            }
            return View(message);
        }

这将自动将您带到“删除确认页面”。但是,您可能希望将其更改为:

        // POST: message/Delete/5
        public ActionResult Delete(int? id)
        {
            if(id !=null){
               message message = db.messages.Find(id);
               db.messages.Remove(message);
               db.SaveChanges();
               return RedirectToAction("Index");
            }
            else
            {
               return HttpNotFound();
            }
        }

此方法“跳过”删除确认页面,同时在 id 不为 null 时仍保持验证。但是,可能需要进一步验证来测试 id 是否真的在 db 中找到。

首先测试您是否发送了一个 id 值,如果是,则在您的数据库中完成“删除”操作。

注意

这些操作在使用 MVC 的脚手架时可以免费使用

【讨论】:

  • 我不想去删除确认页面,这是这里的主要问题
  • @Athul:最后的代码 sn-p 告诉你如何跳过它!
  • OP 的问题在于发布 ID。将 ID 设为可选并不能解决问题。
  • @CodeCaster:这就是为什么在帖子的开头,我已经发送了一个;P
  • @jbutler 这是一个链接,而不是表单帖子。 ;)
【解决方案3】:

试试下面的代码。在您确认之前,它不会将您重定向到删除页面。

@Html.ActionLink("About", "delete", "Issue", new { id = "yourId" }, new { onclick = "return confirm('Are you sure you wish to delete this article?');" })

【讨论】:

  • OP 不想有“你确定吗?”要显示的页面。
【解决方案4】:

您的操作表明删除需要一个 ID,但您在提交表单时没有从视图中传递它。

尝试像这样更改您的代码。 不要忘记用 ID 更改隐藏值。

@using (Html.BeginForm())
{
     @Html.AntiForgeryToken()
     <input type="hidden" name="id" id="id" value="<THE VALUE>"/>        
     <button type="submit" value="delete" formaction="/Issue  /Delete">Delete</button>
}

【讨论】:

  • 所有这些都将我引导到按钮单击的另一个页面(删除页面)
  • @Athul 他的回答是对的,只是他需要指定表单方法 POST。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
相关资源
最近更新 更多