4

単一の子エンティティと他のさまざまなプロパティを持つビューモデルがあります。

私の見解では、子エンティティのフォームを表示したいと思います。次のコードを使用します。

@Html.HiddenFor(model => model.Item.ItemID)

次の出力を生成します。

<input id="Item_ItemID" name="Item.ItemID" type="hidden" value="234" />

ご覧のとおり、Htmlヘルパーには接頭辞idname属性が付いていますが、出力は次のようになります。

<input id="ItemID" name="ItemID" type="hidden" value="234" />

したがって、前者の出力では、フォーム要素が子エンティティのプロパティに対応していないため、フォームの送信時にエラーが発生します。

隠しフィールドをハードコーディングすることでこれを回避できることはわかっています

<input id="ItemID" name="ItemID" type="hidden" value="@Model.Item.ItemID" />

これは、Htmlヘルパーを使用する理由、または部分的なビューを作成して子オブジェクトを渡す理由を無効にします。

@{Html.RenderPartial("ItemForm", Model.Item);}

メソッドにhtml属性を渡すことができ、独自の拡張メソッドを作成できることは知っていますが、データ検証とjQueryが関係している場合、つまり次のコードの場合、状況はさらに複雑になります。

@Html.EditorFor(model => model.Item.Title)
@Html.ValidationMessageFor(model => model.Item.Title)

このコードを生成します:

<input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Item_Title" name="Item.Title" type="text" value="Some text" />
<span class="field-validation-valid" data-valmsg-for="Item.Title" data-valmsg-replace="true"></span>

したがって、プロパティ名の同期を維持するための洗練された方法が必要です。

では、なぜHtmlHelperがビューモデルの子アイテムの属性にプレフィックスを追加するのか、誰かが答えることができますか?そしてフォローアップの質問として、プレフィックスが追加されるのを防ぐ他のきちんとした方法はありますか?

4

1 に答える 1

6

HTML ヘルパーは、モデル バインディング規則を念頭に置いて構築されています。たとえば、次のモデルがあるとします。

public class MyViewModel
{
    public ItemViewModel Item { get; set; }

    // ... other properties
}

public class ItemViewModel
{
    public int ItemID { get; set; }
}

対応するビューは に強く型付けされMyViewModelます。

したがって、使用する場合:

@Html.HiddenFor(model => model.Item.ItemID)

ヘルパーは以下を生成します。

<input id="Item_ItemID" name="Item.ItemID" type="hidden" value="234" />

これにより、フォームがサーバーに POST されたときに、対応するコントローラー アクションでビュー モデルを適切にバインドできるようになります。

[HttpPost]
public ActionResult Process(MyViewModel model)
{
    // model.Item.ItemID will be correctly bound here from the hidden field value
}

あなたの問題は、あなたのコントローラーアクションがItemViewModel代わりに as パラメータを取っているという事実から来ていると思いますMyViewModel:

[HttpPost]
public ActionResult Process(ItemViewModel model)
{
    // model.ItemID will not be correctly bound here from the hidden field value
}

したがって、[Bind]属性を使用してプレフィックスを指定すると、モデル バインダーに役立ちます。

[HttpPost]
public ActionResult Process([Bind(Prefix="Item")] ItemViewModel model)
{
    // model.ItemID will be correctly bound here from the hidden field value
}

または、不要なプロパティをすべて取り除き、Itemプロパティのみを残す別のビュー モデルを単純に設計します。これで、コントローラー アクションは、この特別に設計されたビュー モデルを取ることができます。

したがって、1 日の終わりにわかるように、ビュー モデルを正しく設計すれば、モデル バインディングを完全に微調整できます。ASP.NET MVC のビュー モデルがすべてです。彼らはすべての問題を解決します。

于 2013-01-04T12:53:31.467 に答える