“删除”post方法的参数在ASP.NET MVC中具有空白属性

时间:2021-06-19 13:57:09

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对象传递给控制器​​。也许这是微软的数据完整性问题。所以我猜你必须为所有动作解析整个模型。