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