ADDENDUM: several HTML forms, e.g. in a grid
As an addition to this problem, you need to be very careful with several forms on the same page, for example, in a grid, say, generated using Ajax.BeginForm.
You may be tempted to write something line by line:
@foreach (var username in Model.TutorUserNames) { <tr> <td> @Html.ActionLink(username, MVC.Admin.TutorEditor.Details(username)) </td> <td> @using (Ajax.BeginForm("DeleteTutor", "Members", new AjaxOptions { UpdateTargetId = "AdminBlock", OnBegin = "isValidPleaseWait", LoadingElementId = "PleaseWait" }, new { name = "DeleteTutorForm", id = "DeleteTutorForm" })) { <input type="submit" value="Delete" /> @Html.Hidden("TutorName", username) } </td> </tr> }
The lethal line is here:
@Html.Hidden("TutorName", username)
... and intend to use TutorName as an action parameter. EG:
public virtual ActionResult DeleteTutor(string TutorName){...}
If you do this, the unpleasant surprise you are participating in is that Html.Hidden ("TutorName", username), as Darin Dimitrov explains, displays the last POSTED value. That is, regardless of your cycle, ALL elements will be displayed with the TutorName of the last deleted Tutor!
The word around, in Razor syntax, should replace the @ Html.Hidden call with an explicit input tag:
<input type="hidden" id="TutorName" name="TutorName" value='@username' />
This works as expected.
Those:
NEVER, NEVER USE Html.Hidden TO REVIEW A PARAMETER TO RETURN TO YOUR ACTIONS WHEN YOU USE MULTIPLE FORMS IN A NETWORK !!!
Final warning:
When building a hidden input tag, you need to specify a name and identifier, set the same value, otherwise at the time of writing (February 2011), this will not work correctly. Of course not in Google Chrome. All you get is returning a null parameter if you only have the identifier and attribute of the name.