问题描述:

I would like to pass value from a chosen row to the controller action so that the value will be passed as a session. The passing of value to controller is working, but the thing is, when i press a certain row's button, it keeps on passing the value of the first row. How can i make so that each row's button passes the row's values respectively?

<form Class="form-horizontal" role="form" action="@Url.Action("Lookup", "home")" method="post">

@For Each item In Model.Details

@<tr Class="even gradeC">

<td><input type="hidden" id="id" name="id" value="@item.id">@item.id</td>

<td><input type="hidden" id="name" name="name" value="@item.name">@item.name</td>

<td style="text-align: center; vertical-align: middle;"><Button type="submit" Class="btn btn-default" name="btnSelect" value="@item.id">Select</Button></td>

</tr>

Next

</form>

This is in the controller:

Function Lookup(btnSelect As String, id As String, name As String) As ActionResult

If btnSelect.Equals(id) Then

Session("id") = id

Session("name") = name

End If

End Function

| 1 | Ana | Select |

| 2 | Bella | Select |

When i press button at row 2, it passes value '1' and 'Ana'. I already tried putting the value of id to each button to identify the buttons, but it seemed like it still passes the values of first row, all the times.

When i looked at the values during breakpoint, the value of button is correct - '2' but the value for 'id' and 'name' is always '1' and 'Ana'. What am i missing here? Could anyone help me please?

网友答案:

You have a loop inside your <form> element which is generating duplicate name attributes for your hidden inputs in each iteration (you have multiple inputs with name="id" and name="name").

When you click a submit button, all the name/value pairs of all inputs are posted and the DefaultModelBinder only reads the first one with a matching name and ignores the rest (unless you parameters were IEnumerable(Of String) in which case the parameters would contain an collection of all values).

You code is also generating invalid html because of duplicate id attributes.

You can solve this by generating a new <form> in each iteration

@For Each item In Model.Details
    @<tr Class="even gradeC">
        <td>@item.id</td>
        <td>@item.id</td>
        <td>
            <form Class="form-horizontal" role="form" action="@Url.Action("Lookup", "home")" method="post">
                <input type="hidden" name="id" value="@item.id" />
                <input type="hidden" name="name" value="@item.name" />
                <button type="submit" class="btn btn-default">Select</button>
            </form>
        </td>
    </tr>
Next

Note that the id attributes have been removed, and the name and value attribute from the button has been removed. There is no point in passing back a value for the button since its value is @item.id and your If btnSelect.Equals(id) Then line of code always returns True making it pointless. You controller method should be just

Function Lookup(id As String, name As String) As ActionResult
    Session("id") = id
    Session("name") = name
    ....
End Function

Side note: You do not really need the hidden inputs, and you can simply add the values as route or query sting values in the forms action attribute

action="@Url.Action("Lookup", "home", New With { .id = item.id, .name = item.name })"
相关阅读:
Top