Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BeginForm generates a form action with id

This code:

@using (Html.BeginForm("Rename", "Board", FormMethod.Post))
{
    @Html.LabelFor(x => x.Name);
    @Html.EditorFor(x => x.Name);
    @Html.HiddenFor(x => x.Id);
    <br/>
    <input type="submit" value="@Labels.Submit">
}

Generates the following html:

<form action="/Board/Rename/43" method="post"> // **take a look here**
    <label for="Name">Name</label>
    <input class="text-box single-line" id="Name" name="Name" type="text" value="Board 3" />
    <input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id" type="hidden" value="43" />    
    <br/>
    <input type="submit" value="Submit">
</form>

My actions look like this:

public ActionResult Rename(int id)
{
    var board = _unitOfWork.Boards.GetById(id);
    return View(board);
}

[HttpPost]
public ActionResult Rename(int id, string name)
{
    _unitOfWork.Boards.Rename(id, name);
    _unitOfWork.Commit();
    return RedirectToAction("Board");
}

When I try to submit the form MVC complains:

System.ArgumentException: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Board(Int32)

I guess this is because of the last part of the generated action url ( "/Board/Rename/43" )

Whats the way to do it right?

like image 539
Andrzej Gis Avatar asked Dec 20 '25 16:12

Andrzej Gis


1 Answers

You are correct, the URL generation for the form will take care of the route for you. Meaning, you can actually remove both your Html.BeginForm() parameters and the hidden value for ID.

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.Name);
    @Html.EditorFor(x => x.Name);
    <br/>
    <input type="submit" value="@Labels.Submit">
}

This will actually still generate the same URL to post to that you have now:

<form action="/Board/Rename/43" method="post">

As for why this is failing for you, I would suspect the model binder is getting confused with both an ID parameter in the URL as well as an ID parameter in the form. As for the "right way", typically unless I need to give the form an Id (or class) or need to post to a different action method, I use the basic constructor as shown above. This has a nice effect of being able to reuse the View() that this form came from in multiple places without having to pass a controller, action set of values in the ViewModel.

like image 79
Tommy Avatar answered Dec 22 '25 21:12

Tommy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!