Asp.net mvc “中缺少某些内容”;删除“;MVC中的post方法(EF 4.1)
下面是这个例子 我在删除功能方面遇到问题Asp.net mvc “中缺少某些内容”;删除“;MVC中的post方法(EF 4.1),asp.net-mvc,asp.net-mvc-3,entity-framework,entity-framework-4,Asp.net Mvc,Asp.net Mvc 3,Entity Framework,Entity Framework 4,下面是这个例子 我在删除功能方面遇到问题 [HttpPost] public ActionResult Delete(int id, Blog blog) { try { using (var db = new BlogDataEntities()) { //Having issue here.. as soon as the next line is run in debug //mode .. i
[HttpPost]
public ActionResult Delete(int id, Blog blog)
{
try
{
using (var db = new BlogDataEntities())
{
//Having issue here.. as soon as the next line is run in debug
//mode .. it goes to catch.. and returns a view with null values.
db.Entry(blog).State = System.Data.EntityState.Deleted;
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
在我选中的参数中,“blog”没有得到需要删除的实际blog模型。所有其他方法都可以正常工作(编辑、删除(获取)等)。。
但是删除帖子失败了。我是不是遗漏了什么?提前谢谢你的帮助
编辑:
视图代码
@model DBFirstMVC.Models.Blog
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Blog</legend>
<div class="display-label">Title</div>
<div class="display-field">@Model.Title</div>
<div class="display-label">BloggerName</div>
<div class="display-field">@Model.BloggerName</div>
</fieldset>
@using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" /> |
@Html.ActionLink("Back to List", "Index")
</p>
}
@model DBFirstMVC.Models.Blog
@{
ViewBag.Title=“删除”;
}
删除
是否确实要删除此项?
博客
标题
@模型名称
博客名
@Model.blogger名称
@使用(Html.BeginForm()){
|
@ActionLink(“返回列表”、“索引”)
}
编辑2:
视图中的非Razor代码:
<% using (Html.BeginForm()) { %>
<p>
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "Index") %>
</p>
<% } %>
|
编辑3:(我在aspx中尝试过)
//也尝试了Html.EditorForModel。。
|
最终编辑(更正的解决方案)
@model DBFirstMVC.Models.Blog
@{
ViewBag.Title=“删除”;
}
删除
是否确实要删除此项?
@使用(Html.BeginForm()){
博客
标题
@模型名称
博客名
@Model.blogger名称
|
@ActionLink(“返回列表”、“索引”)
}
是否可以尝试以下操作:
[HttpPost]
public ActionResult Delete(Blog deletedBlog)
{
try
{
using (var db = new BlogDataEntities())
{
// get blog entry from db context!!
Blog blog = db.Blogs.Find(deletedBlog.Id);
//Having issue here.. as soon as the next line is run in debug
//mode .. it goes to catch.. and returns a view with null values.
db.Entry(blog).State = System.Data.EntityState.Deleted;
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch(Exception e)
{
// should catch more specific exception
// but catching 'e' should be a start
return View();
}
}
[更新]-从视图中传入您的博客模型,但正如Dismissile所说,您应该真正使用视图模型,而不是实体模型
此外,您应该捕获内部异常消息,并检查它以获得进一步的线索。上下文可能没有日志条目,因为它没有附加到上下文 您可能需要首先检索博客,然后使用
条目
方法将其标记为已删除:
[HttpPost]
public ActionResult Delete(int id, Blog blog)
{
try
{
using (var db = new BlogDataEntities())
{
// retrieve the blog from the database
var realBlog = db.Blogs.Find(blog.Id);
// nothing to do here, just redirect
if( realBlog == null )
return RedirectToAction("Index");
// since you have the entity just do this instead:
db.Blogs.Remove(realBlog);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch( Exception )
{
return View();
}
}
不过,我不太同意使用实体作为模型的想法。你应该使用视图模型
编辑
既然您现在说博客没有通过,请尝试以下方法:
@model Blog
@using ( Html.BeginForm() )
{
@Html.EditorForModel()
<input type="submit" value="Delete" />
}
@model博客
@使用(Html.BeginForm())
{
@Html.EditorForModel()
}
实际上,您没有向模型绑定器提供构建模型所需的任何详细信息。您的
Delete
操作中的blog
参数很可能为空,因为您只发布了blog的id,而不是整个blog对象。我会修改Delete操作以仅接受id(根据Dismissile的回答),或修改删除视图以发布整个博客对象并从操作中删除id(因为它属于博客对象):
我在几条评论中发表了这篇文章,但我觉得它值得一个单独的“替代”答案 你的控制器应该是纤细的,并且尽可能地贴在地板上 BlogController
public class BlogController : Controller
{
private BlogService blogService;
public BlogService()
{
blogService = new BlogService();
}
[HttpPost]
public ActionResult Delete(int id)
{
// make sure the user has permission to delete before actually deleting
// now that we know the user has permission
if (blogService.Delete(id))
{
return RedirectToAction("Index");
}
else
{
return View();
}
}
}
现在,您将拥有一个可重用的服务层,该服务层依附于
博客服务
public class BlogService
{
private BlogDataEntities dc;
public BlogService()
{
dc = new BlogDataEntities();
}
public bool Delete(int Id)
{
try
{
var blog= (from b in dc.Blogs where Blog.ID == Id select b).First();
// blog doesn't exist, exit and return false.
if( blog == null )
return false;
// blog exists, remove it
dc.Blogs.Remove(blog);
// push the delete to the database
SaveChanges();
// it worked, return true.
return true;
}
catch(System.Exception ex)
{
// an error happened, handle it and return false.
return false;
}
}
// I like to keep my `SubmitChanges()` Separate in case I need to
// stack up a few processes before hitting the database.
public void SaveChanges()
{
dc.SaveChanges();
}
}
捕获异常并查看异常是什么problem@ZVenue我已使用您的新详细信息更新了我的答案。您传递的数据不足,无法构建您的模型。有关非razor语法,请参阅OP中的EDIT2。如何在非razor中编写EditorForModel?仍然不工作,请参阅OP中我的新编辑。谢谢。我发布了有关s的答案将代码中的关注点留给后代,但@Dismissile的观点是正确的答案。唯一的问题是我已经有了一个类似于“获取”Delete的方法。public ActionResult Delete(int id){using(var db=new BlogDataEntities()){return View(db.Blogs.Find(id));}啊,当然。我想得太慢了。你当然需要一个viewmodel传回HttpPost操作。我会稍微修改我的答案…这里也一样..请查看我的评论以获得另一个解决方案..我没有正确地传递博客..我缺少了什么?在这种情况下,deletedBlog在传递到方法时是空的。。为什么模型不能通过点击删除按钮?你的razor视图代码在delete.cshtml中是什么样子的。在你的问题中弹出它,因为我认为这是我的帮助。请参阅OP Edit。是的,博客模型确实没有通过。但是编辑视图代码和操作代码的工作方式相同,编辑操作也很好。它得到了e blog model passed..删除代码与示例中的代码非常相似..但是blog仍然没有被传递..有没有办法强制视图将模型传递给控制器..我尝试了你的解决方案..我认为错误在某个地方..我缺少一些非常简单的东西..blog根本没有被传递..公共活动nResult Delete(int id,Blog Blog)Blog在这里为空..Delete GET方法正确地显示了完整的Blog记录..但是当我单击Delete按钮时,调用了POST方法..在这里我看到Blog没有被传递..它传递了Blog的空值..@ZVenue更新了答案。尝试输入@Html.EditorForModel()在表单标签中的您的视图中,+1对于得出解决方案不屑一顾。我知道删除视图中一定有问题(因此我的评论要求这样做)…你是如何用非剃须刀语法编写的..或者似乎不起作用的..虽然它起作用,但它会给你的应用程序增加不必要的开销。当删除只需要博客帖子的
id
时,为什么要传递整个Blog
对象?这似乎像是向讨厌的蚊子发射了一枚导弹。你唯一需要传递整个Blog
对象的时候de>Blog对象位于C
reate,R
ead,U
pdate上。代码没有明确说明其发布Id或Blog。它只是一个删除按钮。请参见OP中的Edit。Edit具有类似的代码,并且它成功地传递了Blog。@ZVenue-编辑操作接收非空Blog模型的原因是视图发布一个表单,其中包含构造博客对象所需的所有参数。在delete的情况下,传递的唯一参数是id(来自querystring)。
[HttpPost]
public ActionResult Delete(Blog blog)
{
try
{
using (var db = new BlogDataEntities())
{
db.Entry(blog).State = System.Data.EntityState.Deleted;
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
public class BlogController : Controller
{
private BlogService blogService;
public BlogService()
{
blogService = new BlogService();
}
[HttpPost]
public ActionResult Delete(int id)
{
// make sure the user has permission to delete before actually deleting
// now that we know the user has permission
if (blogService.Delete(id))
{
return RedirectToAction("Index");
}
else
{
return View();
}
}
}
public class BlogService
{
private BlogDataEntities dc;
public BlogService()
{
dc = new BlogDataEntities();
}
public bool Delete(int Id)
{
try
{
var blog= (from b in dc.Blogs where Blog.ID == Id select b).First();
// blog doesn't exist, exit and return false.
if( blog == null )
return false;
// blog exists, remove it
dc.Blogs.Remove(blog);
// push the delete to the database
SaveChanges();
// it worked, return true.
return true;
}
catch(System.Exception ex)
{
// an error happened, handle it and return false.
return false;
}
}
// I like to keep my `SubmitChanges()` Separate in case I need to
// stack up a few processes before hitting the database.
public void SaveChanges()
{
dc.SaveChanges();
}
}