I'm having an issue in my MVC application (for making basic CRUD changes to a database) where the object parameter getting passed to my "Delete" post method has blank parameters, even though the object returned by the get method is correct. As a result, when I try to delete the object from the database I get the following exception:
我在我的MVC应用程序中遇到问题(对数据库进行基本的CRUD更改),其中传递给我的“Delete”post方法的对象参数具有空白参数,即使get方法返回的对象是正确的。因此,当我尝试从数据库中删除对象时,我得到以下异常:
A first chance exception of type 'System.ArgumentNullException' occurred in EntityFramework.dll
System.ArgumentNullException: Value cannot be null.
Parameter name: entity
at System.Data.Entity.ModelConfiguration.Utilities.RuntimeFailureMethods.Requires(Boolean condition, String userMessage, String conditionText)
at System.Data.Entity.DbSet`1.Remove(TEntity entity)
at MvcApplication1.HomeController.Delete(ISBN bookToDelete) in C:\Users\MMcCrimmon\Documents\Visual Studio 2012\Projects\MortonPublishingDatabaseInterface\MvcApplication1\Controllers\HomeController.vb:line 103
After a bit of digging I found this question: Missing something in "Delete" post method in MVC (EF 4.1), which seems to be identical, but the answers there did not resolve my problem. What am I doing wrong here?
经过一番挖掘后,我发现了这个问题:在MVC(EF 4.1)的“删除”post方法中遗漏了一些东西,这似乎是相同的,但那里的答案并没有解决我的问题。我在这做错了什么?
Here's my controller code:
这是我的控制器代码:
' GET: /Home/Delete/5
Function Delete(ByVal id As String) As ActionResult
Dim bookToDelete = _db.ISBNs.Find(id)
Return View(bookToDelete)
End Function
' POST: /Home/Delete/5
<HttpPost()> _
Function Delete(bookToDelete As ISBN) As ActionResult
Dim originalBook = _db.ISBNs.Find(bookToDelete.Product_Code)
Try
_db.ISBNs.Remove(originalBook)
_db.SaveChanges()
Return RedirectToAction("Index")
Catch exc As Exception
Return View(originalBook)
End Try
End Function
and here's the view for the Delete page:
这是删除页面的视图:
@ModelType MvcApplication1.ISBN
@Code
ViewData("Title") = "Delete"
Layout = "~/Views/Shared/_Layout.vbhtml"
End Code
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<p/>
<fieldset>
<legend>ISBN</legend>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.Product_Code)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.Product_Code)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.Title)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.Title)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ISBN_UPC)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ISBN_UPC)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ManualName)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ManualName)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.PgCount)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.PgCount)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.BookSize)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.BookSize)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ColorOrBW)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ColorOrBW)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.PageCount)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.PageCount)
</div>
</fieldset>
@Using Html.BeginForm()
@Html.AntiForgeryToken()
@<p>
<input type="submit" value="Delete" /> |
@Html.ActionLink("Back to List", "Index")
</p>
End Using
Following the answer for Missing something in "Delete" post method in MVC (EF 4.1), here's the modified view (still doesn't work):
在MVC(EF 4.1)中的“删除”post方法中找到缺少某些内容的答案后,这里是修改后的视图(仍然不起作用):
@ModelType MvcApplication1.ISBN
@Code
ViewData("Title") = "Delete"
Layout = "~/Views/Shared/_Layout.vbhtml"
End Code
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<p/>
@Using Html.BeginForm()
@Html.AntiForgeryToken()
@<fieldset>
<legend>ISBN</legend>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.Product_Code)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.Product_Code)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.Title)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.Title)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ISBN_UPC)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ISBN_UPC)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ManualName)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ManualName)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.PgCount)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.PgCount)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.BookSize)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.BookSize)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.ColorOrBW)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.ColorOrBW)
</div>
<div class="display-label">
<strong>@Html.DisplayNameFor(Function(model) model.PageCount)</strong>
</div>
<div class="display-field">
@Html.DisplayFor(Function(model) model.PageCount)
</div>
</fieldset>
@<p>
<input type="submit" value="Delete" /> |
@Html.ActionLink("Back to List", "Index")
</p>
End Using
Full disclosure: I'm new to MVC, ASP, and VB.NET, so please forgive me if I'm making some rookie mistake here...
完全披露:我是MVC,ASP和VB.NET的新手,所以如果我在这里犯了一些菜鸟错误,请原谅我...
2 个解决方案
#1
1
You don't seem to be passing the "bookToDelete" parameter through to the DELETE method. In fact you shouldn't be passing this through as it's an object not a simple value. I would pass the "book id" through on delete post action (same as delete get action)
您似乎没有将“bookToDelete”参数传递给DELETE方法。事实上,你不应该通过它,因为它是一个对象而不是一个简单的值。我会通过删除帖子操作传递“书籍ID”(与删除获取操作相同)
Altering the delete view form code by adding the following line between the @Using Html.BeginForm() and End Using lines
通过在@Using Html.BeginForm()和End Using行之间添加以下行来更改删除视图表单代码
@Html.HiddenFor(model => model.id)
@ Html.HiddenFor(model => model.id)
And change the DELETE post method in your controller to
并将控制器中的DELETE post方法更改为
Function Delete(id as string) As ActionResult
函数Delete(id as string)As ActionResult
Dim originalBook = _db.ISBNs.Find(id)
Dim originalBook = _db.ISBNs.Find(id)
#2
0
You need to add a to your form indicating the parameter to pass to your controller. E.g. If your controller is using "BookToDeleteID" as parameter name, your view html should look like this:
您需要在表单中添加一个指示要传递给控制器的参数。例如。如果您的控制器使用“BookToDeleteID”作为参数名称,您的视图html应如下所示:
<form>
......
<input type="hidden" name="BookToDeleteID" value="A_NUMBER"/>
<input type="submit" value="delete"/>
</form>
Sometimes it has weird cases where you have to pass JSON objects to controllers. Maybe it's a data integrity concern by Microsoft. So I guess you have to parse the entire model for all actions.
有时它会出现奇怪的情况,你必须将JSON对象传递给控制器。也许这是微软的数据完整性问题。所以我猜你必须为所有动作解析整个模型。
#1
1
You don't seem to be passing the "bookToDelete" parameter through to the DELETE method. In fact you shouldn't be passing this through as it's an object not a simple value. I would pass the "book id" through on delete post action (same as delete get action)
您似乎没有将“bookToDelete”参数传递给DELETE方法。事实上,你不应该通过它,因为它是一个对象而不是一个简单的值。我会通过删除帖子操作传递“书籍ID”(与删除获取操作相同)
Altering the delete view form code by adding the following line between the @Using Html.BeginForm() and End Using lines
通过在@Using Html.BeginForm()和End Using行之间添加以下行来更改删除视图表单代码
@Html.HiddenFor(model => model.id)
@ Html.HiddenFor(model => model.id)
And change the DELETE post method in your controller to
并将控制器中的DELETE post方法更改为
Function Delete(id as string) As ActionResult
函数Delete(id as string)As ActionResult
Dim originalBook = _db.ISBNs.Find(id)
Dim originalBook = _db.ISBNs.Find(id)
#2
0
You need to add a to your form indicating the parameter to pass to your controller. E.g. If your controller is using "BookToDeleteID" as parameter name, your view html should look like this:
您需要在表单中添加一个指示要传递给控制器的参数。例如。如果您的控制器使用“BookToDeleteID”作为参数名称,您的视图html应如下所示:
<form>
......
<input type="hidden" name="BookToDeleteID" value="A_NUMBER"/>
<input type="submit" value="delete"/>
</form>
Sometimes it has weird cases where you have to pass JSON objects to controllers. Maybe it's a data integrity concern by Microsoft. So I guess you have to parse the entire model for all actions.
有时它会出现奇怪的情况,你必须将JSON对象传递给控制器。也许这是微软的数据完整性问题。所以我猜你必须为所有动作解析整个模型。