2

根据本例.. http://msdn.microsoft.com/en-us/data/gg685489缺少“删除”在MVC POST方法的东西(EF 4.1)

我正在与删除功能的问题。

[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(); 
    } 
} 

在参数我检查'博客'没有得到需要删除的实际博客模型。所有其他方法做工精细(编辑,删除(获取)。等等。 但删除后失败我缺少的东西在此先感谢您的帮助

编辑:?

视图代码

@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> 
} 

编辑2: 非剃刀代码鉴于:

<% using (Html.BeginForm()) { %> 
<p> 
    <input type="submit" value="Delete" /> | 
    <%: Html.ActionLink("Back to List", "Index") %> 
</p> 
<% } %> 

EDIT 3:(我试图在C++)

<% using (Html.BeginForm()) { %> 
<p> 

    <%=Html.DisplayForModel();%> //Tried Html.EditorForModel also.. 
    <input type="submit" value="Delete" /> | 
    <%: Html.ActionLink("Back to List", "Index") %> 
</p> 
<% } %> 

最后编辑(修正方案)

@model DBFirstMVC.Models.Blog 

@{ 
ViewBag.Title = "Delete"; 
} 

<h2>Delete</h2> 

<h3>Are you sure you want to delete this?</h3> 

@using (Html.BeginForm()) { 
<p> 
<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> 

    <input type="submit" value="Delete" /> | 
@Html.ActionLink("Back to List", "Index") 
</fieldset> 
</p> 
} 
+0

捕获异常,看看是什么问题 – Eranga 2012-02-28 15:55:52

+0

@ZVenue我已经更新了我的答案与你的新的细节。您没有传递足够的数据来构建模型。 – Dismissile 2012-02-28 17:04:44

+0

请参阅OP中的EDIT2非剃刀语法..如何在非剃须刀中编写EditorForModel? – ZVenue 2012-02-28 17:21:31

回答

6

上下文可能没有您的博客条目,因为它没有附加到上下文。

你可能需要先检索博客,然后将其标记为使用Entry方法删除:

[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" /> 
} 

你实际上没有给模型绑定任何它所需的细节构建你的模型。

+0

我试过你的解决方案..我认为错在某处..我错过了这里很简单的东西..博客没有被传递.. public ActionResult删除(int id,博客博客)博客是null在这里。 。删除GET方法正确显示完整的博客记录..但是当我点击删除按钮,并且调用POST方法..并且在这里我看到这个博客没有被传递..它为博客传递一个空值。 。 – ZVenue 2012-02-28 16:29:14

+0

@ZVenue更新了答案。尝试将@ Html.EditorForModel()放在窗体标记的视图中。 – Dismissile 2012-02-28 17:05:14

+0

+1解雇抵达解决方案。我知道在删除视图中一定有什么不妥(因此我的评论需要它)。 – 2012-02-28 17:12:23

1

是可以尝试以下方法:

[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所说,你应该真正使用视图模型,而不是实体模型是目的。

另外,您应该捕获内部异常消息并检查以获取更多线索。

+0

唯一的问题是我已经有一种类似于“GET”删除的方法.. public ActionResult Delete(int id) { {var db = new BlogDataEntities()) { return View(db.Blogs。查找(ID)); } } – ZVenue 2012-02-28 16:22:16

+0

啊,当然。在那里想得太慢了。您当然需要将视图模型传回给HttpPost操作。我会修改我的答案有点... – 2012-02-28 16:23:46

+0

同样的事情在这里..请参阅我的评论为其他解决方案..我没有正确传递博客..我错过了什么?在这种情况下,deletedBlog在传递给方法时是空的。为什么模型不能通过点击删除按钮传递? – ZVenue 2012-02-28 16:33:53

1

Delete中的blog参数Action最可能是null,因为您只发布博客的ID,而不是整个博客对象。我会修改删除操作以仅接受id(根据Dismissile的答案),或者修改删除视图以发布整个博客对象并从操作中删除该id(因为它属于博客对象):

[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(); 
    } 
} 
+0

该代码没有明确说明其发布ID或博客..它只是一个删除按钮..请参阅编辑OP。编辑有类似的代码,并成功地通过博客。 – ZVenue 2012-02-28 16:58:43

+2

@Zenue - Edit Action接收非空博客模型的原因是因为视图发布了一个包含构建博客对象所需的所有参数的表单。在删除的情况下,唯一传递的参数是id(来自查询字符串)。 – RoccoC5 2012-02-28 17:19:17

+0

+1您的评论。 – ZVenue 2012-02-28 19:39:34

1

我在一些评论中发布了这个,但我觉得它值得单独回答一个“替代”。

您的控制器应该很苗条,并尽可能地坚持到single responsibility principle

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(); 
     } 
    } 
} 

现在你必须附着在single responsibility principle一个可重用的服务层。

BlogService

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(); 
    } 
}