简体   繁体   中英

ASP MVC passing model data in view back as form data

I got the following Razor view that display a list of HDD so an user and add to a cart. When the user press the button next to each row of HDD, it will pass the quantity and HDD's identity to a controller. However, while each HDD's ID does display properly, "hddId" is always 1 and "quantity" is correctly 5 when I inspect the Controller's parameters.

@model IEnumerable<TestStore.Models.Hdd>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
@using(Html.BeginForm("AddToCart","Cart")){
<table>
    <tr>
        <th>
            Ident
        </th>
        <th>
            Brand
        </th>
        <th>
            Name
        </th>
        <th>
            Model
        </th>
        <th>
            Speed
        </th>
        <th>
            Capacity
        </th>
        <th>
            Cache
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.hddId)
        </td>
        <td>
            @Html.Hidden("hddId", item.hddId)
            @Html.Hidden("quantity", 5)
            @Html.DisplayFor(modelItem => item.brand)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.model)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.speed)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.capacity)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.cache)
        </td>
        <td>
            <input type="submit" value="Add to Cart" />
        </td>
    </tr>

}

</table>
}

Codingbiz is correct. The submit button wasn't referring to any particular row but the entire table. I suspect the reason why "hddId" was always "1" is because that's the first reference of "hddId" it see when the form is submitted. I changed it so @using(Html.BeginForm(...)) is inside the @foreach loop so each row has its own form and submit button:

@foreach (var item in Model) {

    <tr>
        @using(Html.BeginForm("AddToCart","Cart")){
        <td>
            @Html.DisplayFor(modelItem => item.hddId)
        </td>
        <td>
            @Html.Hidden("hddId", item.hddId)
            @Html.Hidden("quantity", 5)
            @Html.DisplayFor(modelItem => item.brand)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.model)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.speed)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.capacity)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.cache)
        </td>
        <td>
            <input type="submit" value="Add to Cart" />
        </td>
        }
    </tr>
}

As others have said, this doesn't work because when you submit, you're submitting every row in the table, not just the one clicked.

One option is to do what they suggest in this article:

http://federmanscripts.com/2010/01/12/form-and-table-row-nesting-workaround/

That is, using javascript, you copy the form values on button press to a hidden row and submit that.

I got around the validation problem by using button type="submit" instead of input type="submit". It still works correctly by passing the id number to the controller.

@using(Html.BeginForm("AddToCart","Cart")){
<table>
    <tr>
    //header stuff here
    </tr>

    @foreach (var item in Model) {
    //row data goes here
    //remove hidden field reference to @item.hddId
    <tr>
    <td>
        <button type="submit" value="@item.hddId" name="hddId">Add to Cart</button>
    </td>
    </tr>
</table>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM