BeginForm使用id生成表单操作

时间:2013-10-30 22:57:14

标签: c# .net asp.net-mvc asp.net-mvc-4 razor

此代码:

@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">
}

生成以下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>

我的行为如下:

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");
}

当我尝试提交表单时,MVC抱怨:

  

System.ArgumentException:参数字典包含null   非可空类型'System.Int32'的参数'id'的条目   方法'System.Web.Mvc.ActionResult Board(Int32)

我想这是因为生成的动作网址的最后一部分(“/ Board / Rename / 43 ”)

这样做的方法是什么?

1 个答案:

答案 0 :(得分:2)

您是对的,表单的URL生成将为您处理路由。这意味着,您实际上可以删除Html.BeginForm()参数和ID的隐藏值。

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

这实际上仍会生成相同的网址,以便发布到您现在拥有的网址:

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

至于为什么这对你失败,我怀疑模型绑定器会与URL中的ID参数以及表单中的ID参数混淆。至于“正确的方式”,通常除非我需要给表单一个Id(或类)或需要发布到不同的操作方法,我使用如上所示的基本构造函数。这具有很好的效果,能够在多个位置重用此表单来自的View(),而无需在ViewModel中传递控制器,操作值集。