3

このコード:

@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: パラメーター ディクショナリには、メソッド 'System.Web.Mvc.ActionResult Board(Int32) の null 非許容型 'System.Int32' のパラメーター 'id' の null エントリが含まれています

これは、生成されたアクション URL の最後の部分 ( "/Board/Rename/ 43 " )が原因だと思います。

それを正しく行う方法は何ですか?

4

1 に答える 1

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

これにより、実際には、現在と同じ投稿先の URL が生成されます。

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

これが失敗する理由については、モデル バインダーが URL の ID パラメーターとフォームの ID パラメーターの両方と混同されているのではないかと思います。「正しい方法」については、通常、フォームに Id (またはクラス) を与える必要があるか、別のアクション メソッドに投稿する必要がない限り、上記の基本的なコンストラクターを使用します。これにより、ViewModel で値のコントローラーやアクション セットを渡すことなく、このフォームの元となった View() を複数の場所で再利用できるという優れた効果が得られます。

于 2013-10-30T22:59:25.187 に答える