web-dev-qa-db-ja.com

MVC 4 Razor、部分ビューの投稿フォーム

MVC 4とカミソリは初めてです。複数の部分ビューを含むビューがあります。部分ビューの機能により、これらを他のビューでも再利用する予定です。

私のモデルは複雑なオブジェクトのコレクションです:

    public class EmployeeInfo
    {
        public EmployeeContactInfo contactInfo { get; set; }
        public List<TelephoneInfo> phoneDetails { get; set; }
        public AddressDetails addressDetails { get; set; }
    }

私のメインビューのモデルはEmployeeInfoであり、他の部分ビューにはTelephoneInfoEmployeeContactInfoAddressDetailsのモデルがあります。

RenderPartialRenderActionおよびPartialを使用して、部分ビューをロードしようとしました。例:

    @using (Html.BeginForm())
    {
    @Html.Partial("ContactInfo",Model.contactInfo)
    }

メインフォームが送信されると、メインモデルには部分ビューの更新された値がありません。

私はこれを検索し、以下の2つの提案された解決策を見つけました:

  1. Use EditorFor-動作し、モデルが更新されますが、テキストボックスだけでなく、いくつかの内部操作(アドレスの検索など)を持つ他のコントロールのコレクションもあり、他の場所で同じ部分ビューを再利用する必要があります(従来のASP.NETのユーザーコントロールのような)

  2. RenderActionの代わりにRenderPartialを使用します-私にはうまくいきませんでした。

間違っているか、何か間違ったことを理解したかどうかを教えてください。

14
indranil pal

もう1つの選択肢は、 エディターテンプレート を作成することです。たとえば、メインビューで:

@using (Html.BeginForm())
{
    @(Html.EditorFor(m => m.ContactInfo))
}

ここで、Views/Sharedフォルダー(またはViews/HomeなどのViews/ControllerNameフォルダー)で、「EditorTemplates」という名前の新しいフォルダーを作成します。その新しいフォルダーにEmployeeContactInfo.cshtmlという名前のcshtmlビューファイルを作成します(ヒント、cshtmlの名前はデータ型名である必要があります。例:stringbool、またはこの場合は顧客の連絡先情報タイプ)。そのビューファイルに、次のようなものを入れます。

@model EmployeeContactInfo

@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)

コントローラにポストバックすると、返されたモデルの一部として値が含まれます。

25
Jason Evans

問題は、メインフォームがcontactInfo.propertyという名前の要素を予期していることです。おそらく、生成する名前の一部が正しい識別子のないプロパティであるため、この問題によりMVCのデフォルトモデルバインダーに問題が発生します。カスタムモデルバインダーを作成できますが、手間がかかります。または、少ない作業で問題を解決する2つの方法があります。

1。生成された要素の名前を強制する

たとえば、EmployeeContactInfoクラスに文字列Addressプロパティが含まれる場合、このヘルパーを使用する必要があります。

@Html.TextBox("contactInfo.Address", model.Address)

その結果:

<input type="text" name="contactInfo.Address" id="contactInfo_Address" />

の代わりに:

@Html.TextBoxFor(m=> m.Address)

その結果:

<input type="text" name="Address" id="Address" />

2。モデル全体を渡す:

モデル全体を渡すと、生成された名前が正しいため、ヘルパーを使用できます。

@Html.TextBoxFor(m=> m.contactInfo.Address)

その結果:

<input type="text" name="contactInfo.Address" id="contactInfo_Address" />
7
Daniele