web-dev-qa-db-ja.com

ASP.NET MVC:HtmlHelper.Hiddenを使用して非表示フィールド値がレンダリングされない

私のアプリでかなり奇妙なことが起こっています:

ViewModelに次のプロパティがあります。

public int? StakeholderId { get; set; }

次のようにpartialビューでレンダリングされます:

<%= Html.Hidden("StakeholderId", Model.StakeholderId) %>

フォームが送信され、関連するコントローラーアクションがIDを生成し、モデルを更新してから、更新されたモデルと同じビューを返します

私が経験している問題は、StakeholderIdに値が設定されていても、非表示フィールドの2回目にレンダリングされる「値」属性に何も含まれていないことです。

値を出力するだけの場合、ページに表示されるので、これを実行して値をレンダリングします。

<input type="hidden" id="StakeholderId" name="stakeholderId" value="<%: Model.StakeholderId %>" />

しかし、ヘルパーが更新された値を受け取らないのはかなり奇妙です?

(私はフォームを送信し、アクション結果をdivにレンダリングするためにjQueryを使用していますが、jQueryがそれを処理する前にチェックし、返されたhtmlがすでに間違っているので、それはあまり関係がないと思います何でも)

[〜#〜] update [〜#〜]

それ以来、コントローラーアクションが部分ビューを返す前に、関連するModelStateキーをクリアできることを発見しました。

70
Veli Gebrev

ヘルパーは最初にPOSTされた値を探して使用します。フォームを投稿すると、IDの古い値が取得されます。回避策は正しいです。

60
Darin Dimitrov

補遺:グリッドなどの複数のHTMLフォーム

この問題に対する補遺として、非常に注意するべきことの1つは、たとえばAjax.BeginFormを使用して生成されたグリッドなど、同じページに複数のフォームを配置することです。

次のような行に沿って何かを書きたくなるかもしれません。

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

ここでの致命的なラインは次のとおりです。

@Html.Hidden("TutorName", username)

...そして、TutorNameをアクションのパラメーターとして使用する予定です。例えば:

public virtual ActionResult DeleteTutor(string TutorName){...}

これを行うと、あなたがいる厄介な驚きは、Html.Hidden( "TutorName"、username)が、Darin Dimitrovが説明するように、最後にPOSTされた値をレンダリングすることです。つまり、ループに関係なく、すべてのアイテムは最後に削除された先生のTutorNameでレンダリングされます!

Razor構文での単語は、@ Html.Hidden呼び出しを明示的な入力タグに置き換えることです。

<input type="hidden" id="TutorName" name="TutorName" value='@username' />

これは期待どおりに機能します。

すなわち:

決して、Htmlを使用しないでください。グリッドで複数のフォームを使用している場合、アクションにパラメータを渡すために非表示!!!

最終警告:

非表示の入力タグを作成するときは、同じ値に設定された名前とIDの両方を含める必要があります。そうしないと、執筆時点(2011年2月)で正しく機能しません。確かにGoogle Chromeではありません。取得できるのは、idのみがあり、name属性がない場合に返されるnullパラメータのみです。

34
awrigley